는 주석을 사용해야 하:@IdClass 또는@EmbeddedId
-
03-07-2019 - |
문제
이 JPA
(자바 Persistence API)사양은 2 가지 방법을 지정 엔터티 복합 열쇠: @IdClass
고 @EmbeddedId
.
나는 모두 사용하는 주석에 매핑된 엔지만,그것은 것으로 밝혀졌 큰 혼란을되지 않은 사람들이 매우 친숙한 JPA
.
고 싶어를 채택 하나만을 지정하는 방법을 복합 키를 사용합니다.하나는 정말 최고입니까?왜?
해결책
나는 그것을 고려한다 @EmbeddedId
아마도 더 장점 일 것입니다 @IdClass
모든 필드 액세스 연산자를 사용하여 전체 기본 키 객체에 액세스 할 수 없습니다. 사용 @EmbeddedId
당신은 이것을 좋아할 수 있습니다 :
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
이는 필드에 대한 명확한 개념을 제공합니다. 필드는 필드 액세스 연산자에 액세스하는 클래스에서 모두 집계되어 있기 때문에 복합 키를 만드는 필드를 명확하게 제공합니다.
또 다른 차이점 @IdClass
그리고 @EmbeddedId
HQL을 쓰는 것은 다음과 같습니다.
와 함께 @IdClass
당신은 쓰기:
select e.name from Employee e
그리고 함께 @EmbeddedId
당신은 다음을 작성해야합니다.
select e.employeeId.name from Employee e
동일한 쿼리에 대해 더 많은 텍스트를 작성해야합니다. 어떤 사람들은 이것이 홍보 된 것과 같은 자연 언어와 다르다고 주장 할 수도 있습니다. IdClass
. 그러나 대부분의 시대는 주어진 필드가 복합 키의 일부라는 쿼리에서 바로 이해하는 것이 매우 도움이된다는 것입니다.
다른 팁
idclass 대신 embeddedid를 사용해야하는 인스턴스를 발견했습니다. 이 시나리오에는 추가 열이 정의 된 조인 테이블이 있습니다. 나는 idclass를 사용 하여이 문제를 해결하여 조인 테이블의 행을 명시 적으로 나타내는 엔티티의 키를 나타냅니다. 나는 그것을 이런 식으로 일할 수 없었다. 고맙게도 "Hibernate와의 Java Persistence"에는이 주제에 전념하는 섹션이 있습니다. 제안 된 하나의 솔루션은 광산과 매우 유사했지만 대신 embeddedid를 사용했습니다. 책에서 그 후에 내 객체를 모델링했습니다. 이제 올바르게 동작합니다.
복합 기본 키를 사용하기위한 세 가지 전략이 있습니다.
- 표시하십시오
@Embeddable
그리고 당신의 엔티티 클래스 A 클래스 A 일반 속성에 추가하십시오.@Id
. - Entity Class A Class A 일반 속성에 추가하여 표시됩니다.
@EmbeddedId
. - 모든 필드에 대한 엔티티 클래스에 속성을 추가하고
@Id
, 그리고 당신의 엔티티 클래스를 표시하십시오@IdClass
, 기본 키 클래스의 클래스를 제공합니다.
사용 @Id
수업이 표시되어 있습니다 @Embeddable
가장 자연스러운 접근법입니다. 그만큼 @Embeddable
어쨌든 태그는 비 예측 키 임베드 가능 값에 사용할 수 있습니다. 복합 기본 키를 단일 속성으로 취급 할 수 있으며 재사용을 허용합니다. @Embeddable
다른 테이블에서 수업.
다음으로 가장 자연스러운 접근법은 @EmbeddedId
꼬리표. 여기서 기본 키 클래스는 다른 테이블에서 사용할 수 없습니다. @Embeddable
엔티티이지만 키를 일부 클래스의 단일 속성으로 취급 할 수 있습니다.
마지막으로, 사용 @IdClass
그리고 @Id
주석을 사용하면 기본 키 클래스의 속성 이름에 해당하는 엔티티 자체의 속성을 사용하여 복합 1 차 키 클래스를 매핑 할 수 있습니다. 이름은 해당해야하며 (이를 재정의하는 메커니즘은 없음) 기본 키 클래스는 다른 두 기술과 동일한 의무를 존중해야합니다. 이 접근법의 유일한 장점은 Enclosing Entity의 인터페이스에서 기본 키 클래스의 사용을 "숨기는"능력입니다. 그만큼 @IdClass
주석은 클래스 유형의 값 매개 변수를 취하며, 이는 클래스가 복합 기본 키로 사용되어야합니다. 사용될 기본 키 클래스의 속성에 해당하는 필드는 모두 주석을 달아야합니다. @Id
.
멀리로 나가 알고 있는 경우에 당신의 복합 PK 포함 FK 더욱 쉽고 간단하게 사용 @IdClass
가 @EmbeddedId
당신은 매핑을 정의하는 귀하의 FK 열 두 번 onece 에 @Embeddedable
한 번으로 즉 @ManyToOne
가 @ManyToOne
은 읽기만 가능(@PrimaryKeyJoinColumn
)기 때문에 있을 수 없습의 열정 두 개의 변수(가능한 갈등).
그래서 당신이 설정하 FK 를 사용하여 간단한 형식 @Embeddedable
.
다른 사이트 사용 @IdClass
이 상황에 처리할 수 있으로 훨씬 더 쉽게 표시 기본키를 통해 OneToOne 및 ManyToOne 관계:
예 JPA2.0ManyToOne id 는 주석
...
@Entity
@IdClass(PhonePK.class)
public class Phone {
@Id
private String type;
@ManyToOne
@Id
@JoinColumn(name="OWNER_ID", referencedColumnName="EMP_ID")
private Employee owner;
...
}
예 JPA2.0id 를 클래스
...
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
.
복합 키에는 an이 없어야합니다 @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