복합키 구현 + 비식별 관계 매핑

신상현·2021년 4월 28일
0

Spring Boot와 JPA

목록 보기
15/16

복합 키를 갖는 부모 클래스 구성

1. @IdClass 사용

DB에 맞춘 방법

  1. 식별자 클래스(ParentId.class) 생성
  1. equalshashCode를 오버라이딩하여 구현

  2. 주의점

    • 식별자 클래스의 속성명과 그걸 사용하는 엔티티에서의 속성명이 같아야 한다.
    • 식별자 클래스는 public 이어야 한다.
    • 기본 생성자가 필요하다.
    • Serializable 인터페이스를 구현해야 한다.
public class ParentId implements Serializable {
	
    private Long id1;
    private Long id2;
    
    // 기본 생성자
    public ParentId(){}
    
    public ParentId(Long id1, Long id2){
    	this.id1 = id1;
        this.id2 = id2;
    }
    
    @Override
    public boolean equals(Object o){...}
    
    @Override
    public int hashCode(){...}
    
}
  1. 복합키를 갖는, 식별자 클래스를 사용할 엔티티에서 @IdClass(ParentId.class)와 같이 식별자 클래스를 매핑해준다.
@Entity
@IdClass(ParentId.class)
public class Parent {
	
    @Id
    private Long id1;
    
    @Id
    private Long id2;
    
    ...
}
  1. 복합 키를 사용하는 엔티티를 저장할 때, 해당 엔티티의 복합 키의 값만 지정해준다. 그러면 내부적으로 알아서, 해당 값들로 식별자 클래스(ParentId)를 생성하고, 영속성 컨텍스트의 키 값으로 사용한다.

  2. 따라서, 저장할 때는 식별자 클래스를 지정해서 저장하지 않았음에도 불구하고, 조회할 때는 식별자 클래스의 값으로 영속성 컨텍스트에서 조회해야 한다.

  3. 자식 클래스 구성

@Entity
public class Child {
	
    @Id
    private Long id;
    
    @ManyToOne
    @JoinColumns({ // 속성이랑 컬럼이랑 같으면, 후자는 생략 가능
    	@JoinColumn(name="parent_id1", referencedColumnName = "id1"),
        @JoinColumn(name="parent_id2", referencedColumnName = "id2")
    })
    private Parent parent;
    
}

‼‼ 이건 내가 헷갈려서 ‼‼


2. @EmbeddedId

좀 더 객체지향에 맞춘 방법

  1. 식별자 클래스(ParentId)는 @Embeddable 어노테이션 사용
@Embeddable
public class ParentId implements Serializable {
  
  private Long id1;
  private Long id2;
  
    @Override
    public boolean equals(Object o){...}
    
    @Override
    public int hashCode(){...}
}
  1. 식별자 클래스(ParentId)를 복합 키를 사용하는 클래스(Parent)에 속성으로 직접 매핑한다. @EmbeddedId 어노테이션을 사용한다.
@Entity
public class Parent {
  
  @EmbeddedId
  private ParentId id;
  
  private String name;
  
  //equals and hashCode 구현
  ...
}
  1. 복합 키를 사용하는 엔티티를 저장할 때, 직접 식별자 클래스(parentId)를 생성 후, 엔티티에 속성 값을 설정 해준 다음 저장한다.

  2. 조회는 식별자 클래스를 통해서 일어난다.

equalshashCode

복합 키를 구성하는 식별자 클래스에 필수적으로 구현해야 한다.

영속성 컨텍스트는 식별자를 통해서 엔티티를 관리한다. 그리고 식별자를 구분할 때는 equalshashCode를 사용한다.

하지만, Object 클래스가 제공하는 기본 equals()는 인스턴스의 참조 값 비교인 ==, 동일성 비교만을 제공한다.

따라서, equalshashCode를 구현하지 않는다면, 영속성 컨텍스트가 엔티티를 관리하는데 문제를 발생시킨다.

@GeneratedValue

복합 키를 사용하게 되면, @GeneratedValue를 사용할 수 없다.
여러 개 중, 단 하나라도 적용 불가!

profile
개발자 싱상형

0개의 댓글