JPA
(자바 퍼시스턴스 API) 규격은 기업 복합 키를 지정하는 2 가지 방법이 있습니다 @IdClass
와 @EmbeddedId
.
매핑 된 엔터티에 두 주석을 모두 사용하고 있지만에 익숙하지 않은 사람들에게는 큰 혼란으로 판명되었습니다 JPA
.
복합 키를 지정하는 한 가지 방법 만 채택하고 싶습니다. 어느 것이 정말 최고입니까? 왜?
답변
필자 @EmbeddedId
는 @IdClass
필드 액세스 연산자를 사용하여 전체 기본 키 객체에 액세스 할 수 없기 때문에 더 자세한 정보 라고 생각합니다 . 를 사용하면 @EmbeddedId
다음과 같이 할 수 있습니다.
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
이것은 필드 액세스 연산자를 통해 액세스되는 클래스에 모두 모이기 때문에 복합 키를 만드는 필드에 대한 명확한 개념을 제공합니다.
HQL을 작성할 때 와 다른 또 다른 차이점은 다음 @IdClass
과 @EmbeddedId
같습니다.
@IdClass
당신 과 함께 쓰기 :
직원 e에서 e.name을 선택하십시오.
그리고 @EmbeddedId
당신은 다음 과 같이 작성해야합니다 :
직원 e에서 e.employeeId.name을 선택하십시오.
동일한 쿼리에 대해 더 많은 텍스트를 작성해야합니다. 어떤 사람들은 이것이 이것에 의해 장려 된 것과 같은보다 자연스러운 언어와 다르다고 주장 할 수도 있습니다 IdClass
. 그러나 대부분의 경우 주어진 필드가 복합 키의 일부라는 쿼리에서 이해하는 것은 매우 도움이됩니다.
답변
복합 기본 키를 사용하는 세 가지 전략이 있습니다.
- 로 표시하고로
@Embeddable
표시된 일반 속성을 엔티티 클래스에 추가하십시오@Id
. - 로 표시된 일반 속성을 엔티티 클래스에 추가하십시오
@EmbeddedId
. - 모든 필드에 대해 엔티티 클래스에 특성을 추가하고로 표시하고
@Id
엔티티@IdClass
키를로 표시하여 기본 키 클래스의 클래스를 제공하십시오.
@Id
로 표시된 클래스와 함께 사용하는 @Embeddable
것이 가장 자연스러운 방법입니다. @Embeddable
태그 어쨌든 기본 키가 아닌 임베드 값을 사용할 수 있습니다. 복합 기본 키를 단일 특성으로 취급하고 @Embeddable
다른 테이블 에서 클래스를 재사용 할 수 있습니다.
다음으로 가장 자연스러운 방법은 @EmbeddedId
태그를 사용하는 것입니다 . 여기서 기본 키 클래스는 @Embeddable
엔티티 가 아니기 때문에 다른 테이블에서 사용할 수 없지만 키를 일부 클래스의 단일 속성으로 취급 할 수 있습니다.
마지막으로 @IdClass
and @Id
주석을 사용하면 기본 키 클래스의 속성 이름에 해당하는 엔터티 자체의 속성을 사용하여 복합 기본 키 클래스를 매핑 할 수 있습니다. 이름은 일치해야하며 (이를 재정의하는 메커니즘은 없습니다) 기본 키 클래스는 다른 두 기술과 동일한 의무를 준수해야합니다. 이 접근법의 유일한 장점은 엔 클로징 엔티티의 인터페이스에서 기본 키 클래스의 사용을 “숨기는”기능입니다. @IdClass
주석은 클래스 화합물 일차 키로서 사용될 수 있어야 클래스 유형 값 파라미터를 취. 사용할 기본 키 클래스의 속성에 해당하는 필드에는 모두 주석이 달려 있어야합니다 @Id
.
참조 : http://www.apress.com/us/book/9781430228509
답변
IdClass 대신 EmbeddedId를 사용해야하는 인스턴스를 발견했습니다. 이 시나리오에는 추가 열이 정의 된 조인 테이블이 있습니다. 조인 테이블의 행을 명시 적으로 나타내는 엔터티의 키를 나타 내기 위해 IdClass를 사용 하여이 문제를 해결하려고했습니다. 나는 이런 식으로 작동하지 못했습니다. 고맙게도 “Hibernate에 대한 Java Persistence”에는이 주제에 대한 섹션이 있습니다. 제안 된 솔루션 중 하나는 내 것과 매우 유사하지만 대신 EmbeddedId를 사용했습니다. 나는 책에있는 것들이 이제 올바르게 동작하는 것을 따라 나의 물건들을 모델링했다.
답변
복합 PK에 FK가 포함되어 있는지 아는 한 사용하기가 더 쉽고 간단합니다. @IdClass
으로 @EmbeddedId
당신이 두 번 onece 당신의 FK 컬럼에 대한 매핑을 정의해야 @Embeddedable
하고 일단 즉하는 한 @ManyToOne
곳 @ManyToOne
읽기 전용 수 (가 @PrimaryKeyJoinColumn
) 당신은 두 개의 변수 (가능한 충돌) 한 열 집합을 가질 수 있기 때문이다.
따라서 간단한 유형을 사용하여 FK를 설정해야합니다 @Embeddedable
.
@IdClass
이 상황을 사용하는 다른 사이트 에서는 OneToOne 및 ManyToOne Relationships를 통해 기본 키에 표시된 것처럼 훨씬 쉽게 처리 할 수 있습니다 .
JPA 2.0 ManyToOne ID 주석 예
...
@Entity
@IdClass(PhonePK.class)
public class Phone {
@Id
private String type;
@ManyToOne
@Id
@JoinColumn(name="OWNER_ID", referencedColumnName="EMP_ID")
private Employee owner;
...
}
JPA 2.0 ID 클래스 예
...
public class PhonePK {
private String type;
private long owner;
public PhonePK() {}
public PhonePK(String type, long owner) {
this.type = type;
this.owner = owner;
}
public boolean equals(Object object) {
if (object instanceof PhonePK) {
PhonePK pk = (PhonePK)object;
return type.equals(pk.type) && owner == pk.owner;
} else {
return false;
}
}
public int hashCode() {
return type.hashCode() + owner;
}
}
답변
가장 큰 장점은 ?를 @GeneratedValue
사용할 때 ID에 사용할 수 있다는 것 입니다 @IdClass
. 에 사용할 수 없다고 확신 @GeneratedValue
합니다 @EmbeddedId
.
답변
복합 키를 사용할 @Id
때는 속성 이 없어야합니다 @EmbeddedId
.
답변
EmbeddedId를 사용하면 예를 들어 HQL에서 IN 절을 사용할 수 있습니다. FROM Entity WHERE id IN :ids
여기서 id는 EmbeddedId이지만 IdClass와 동일한 결과를 얻는 것은 고통 스럽습니다.FROM Entity WHERE idPartA = :idPartA0 AND idPartB = :idPartB0 .... OR idPartA = :idPartAN AND idPartB = :idPartBN