JPA 복합 키 + 시퀀스
-
04-07-2019 - |
문제
일반 JPA 또는 JPA+Hibernate 확장에서 복합 키의 요소가 시퀀스 인 Composite 키를 선언하는 것이 가능합니까?
이것은 내 복합 수업입니다.
@Embeddable
public class IntegrationEJBPk implements Serializable {
//...
@ManyToOne(cascade = {}, fetch = FetchType.EAGER)
@JoinColumn(name = "APPLICATION")
public ApplicationEJB getApplication() {
return application;
}
@Column(name = "ENTITY", unique = false, nullable = false, insertable = true, updatable = true)
public String getEntity() {
return entity;
}
@GeneratedValue(strategy = GenerationType.AUTO, generator = "INTEGRATION_ID_GEN")
@SequenceGenerator(name = "INTEGRATION_ID_GEN", sequenceName = "OMP_INTEGRATION_CANONICAL_SEQ")
@Column(name = "CANONICAL_ID", unique = false, nullable = false, insertable = true, updatable = true)
public String getCanonicalId() {
return canonicalId;
}
@Column(name = "NATIVE_ID", unique = false, nullable = false, insertable = true, updatable = true)
public String getNativeId() {
return nativeId;
}
@Column(name = "NATIVE_KEY", unique = false, nullable = false, insertable = true, updatable = true)
public String getNativeKey() {
return nativeKey;
}
//...
}
나는 이미 값을 제공합니다 application
, entity
, nativeId
그리고 nativeKey
. 아래와 같은 엔티티를 구성하고 싶습니다.
IntegrationEJB i1 = new IntegrationEJB();
i1.setIntegrationId(new IntegrationEJBPk());
i1.getIntegrationId().setApplication(app1);
i1.getIntegrationId().setEntity("Entity");
i1.getIntegrationId().setNativeId("Nid");
i1.getIntegrationId().setNativeKey("NK");
그리고 내가 전화 할 때 em.persist(i1
), 나는 그것을 원한다 canonicalId
생성되고 통합이 삽입됩니다.
이게 가능해? 그렇다면 단순한 방법은 무엇입니까? (응용 프로그램 제공 키나 기본 SQL을 사용하지 않는 것이 좋습니다).
해결책
나는 이것이 일반 JPA에서는 불가능하다고 생각합니다.
다른 팁
복합 PKS에 @generatedValue를 사용하는 것은 JPA 2 사양과 함께 지정되지 않습니다.
JPA 사양에서 :
11.1.17 생성 값 주석
생성 값 주석은 기본 키 값에 대한 생성 전략의 사양을 제공합니다. 생성 값 주석은 ID 주석과 함께 기업의 기본 키 속성 또는 엔티티 또는 매핑 된 슈퍼 클래스에 적용될 수 있습니다. [97] 생성 값 주석의 사용은 간단한 기본 키에 대해서만 지원되면됩니다. 생성 값 주석의 사용은 파생 된 기본 키에 대해 지원되지 않습니다.
다른 시나리오에서는 @generatedValue를 사용하는 간단한 PK (@ID)가있는 상위 엔티티를 가질 수 있으며 부모로부터 생성 된 ID를 포함하는 복합 PK와 다른 열이 포함 된 하위 엔티티가있을 수 있습니다.
- 어린이에게 부모 엔티티와의 @ManyToOne 관계를 제공하여 생성 된 ID를 FK 열에서 상속합니다.
- 그런 다음 엔티티에 지정된 @idclass와 엔티티 내의 두 개의 @ID 열을 통해 합성 PK를 자식에게 제공하십시오.
@Entity public class ParentEntity {
@Id
@GenerateValue(IDENTITY) // If using DB auto-increment or similar
int id;
// ...
}
@Entity @IdClass(ChildId.class) public class ChildEntity { // The child table will have a composite PK: // (parent_ID, child_name) @Id @ManyToOne int parentEntity;
@Id
String childName;
String favoriteColor; // plus other columns
// ...
}
// child Id attributes have the same name as the child entity // however the types change to match the underlying PK attributes // (change ParentEntity to int) public class ChildId implements Serializable {
int parentEntity;
String childName;
public ChildId() { //... }
// Add extra constructor & remove setter methods so Id objects are immutable
public ChildId(int parentEntity, String childName) { //... }
public int getParentEntity() { //... }
// make Id objects immutable:
// public void setParentEntity(int parentEntity) { //... }
public String getChildName() { //... }
// public void setChildName(String childName) { //... }
}
이렇게 시도하십시오 :
@TableGenerator(name = "canonicalKeys", allocationSize = 1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "canonicalKeys")
@Column(name = "CANONICAL_ID", unique = false, nullable = false, insertable = true, updatable = true)
public String getCanonicalId() {
return canonicalId;
}
이러한 방식으로 시퀀스를 사용하는 대신 테이블을 사용할 수 있습니다.
나는 그것이 당신의 건물이 이와 같은 복합 기본 키로 보인다는 것을 알았습니다. 예시. 내 데이터베이스에서 비슷한 문제를 겪는 동안 SQL을 직접 호출 할 수 있는지 궁금했습니다.
select nextval ('hibernate_sequence')
나는 그것이 바람을 피우고 있다고 생각한다 ;-)