@IdClass 사용DB에 맞춘 방법
ParentId.class) 생성equals와 hashCode를 오버라이딩하여 구현
주의점
public 이어야 한다.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(){...}
}
@IdClass(ParentId.class)와 같이 식별자 클래스를 매핑해준다.@Entity
@IdClass(ParentId.class)
public class Parent {
@Id
private Long id1;
@Id
private Long id2;
...
}
복합 키를 사용하는 엔티티를 저장할 때, 해당 엔티티의 복합 키의 값만 지정해준다. 그러면 내부적으로 알아서, 해당 값들로 식별자 클래스(ParentId)를 생성하고, 영속성 컨텍스트의 키 값으로 사용한다.
따라서, 저장할 때는 식별자 클래스를 지정해서 저장하지 않았음에도 불구하고, 조회할 때는 식별자 클래스의 값으로 영속성 컨텍스트에서 조회해야 한다.
자식 클래스 구성
@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;
}
‼‼ 이건 내가 헷갈려서 ‼‼
@EmbeddedId좀 더 객체지향에 맞춘 방법
ParentId)는 @Embeddable 어노테이션 사용@Embeddable
public class ParentId implements Serializable {
private Long id1;
private Long id2;
@Override
public boolean equals(Object o){...}
@Override
public int hashCode(){...}
}
ParentId)를 복합 키를 사용하는 클래스(Parent)에 속성으로 직접 매핑한다. @EmbeddedId 어노테이션을 사용한다.@Entity
public class Parent {
@EmbeddedId
private ParentId id;
private String name;
//equals and hashCode 구현
...
}
복합 키를 사용하는 엔티티를 저장할 때, 직접 식별자 클래스(parentId)를 생성 후, 엔티티에 속성 값을 설정 해준 다음 저장한다.
조회는 식별자 클래스를 통해서 일어난다.
equals와 hashCode복합 키를 구성하는 식별자 클래스에 필수적으로 구현해야 한다.
영속성 컨텍스트는 식별자를 통해서 엔티티를 관리한다. 그리고 식별자를 구분할 때는 equals와 hashCode를 사용한다.
하지만, Object 클래스가 제공하는 기본 equals()는 인스턴스의 참조 값 비교인 ==, 동일성 비교만을 제공한다.
따라서, equals와 hashCode를 구현하지 않는다면, 영속성 컨텍스트가 엔티티를 관리하는데 문제를 발생시킨다.
@GeneratedValue복합 키를 사용하게 되면, @GeneratedValue를 사용할 수 없다.
여러 개 중, 단 하나라도 적용 불가!