JPA复合键+序列

在普通的JPA或JPA + Hibernate扩展中是否可以声明一个复合键,其中复合键的一个元素是一个序列?

这是我的复合类:

@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; } //... } 

我已经为applicationentitynativeIdnativeKey提供了值。 我想构建一个如下所示的实体:

 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是不可能的。

在JPA 2规范中未指定使用@GeneratedValue用于复合PK。

从JPA规范:

11.1.17 GeneratedValue注释

GeneratedValue注释提供了主键值的生成策略的规范。 GeneratedValue注释可以与Id注释一起应用于实体或映射超类的主键属性或字段。[97] 仅需要支持简单主键使用GeneratedValue注释。 派生主键不支持使用GeneratedValue注释。

请注意,在不同的场景下,您可以拥有一个使用@GeneratedValue的简单PK(@Id)的父实体,然后让一个子实体具有一个复合PK,其中包含来自父级的生成的Id以及另一列。

  • 为子实体提供@ManyToOne关系,以便它在FK列中inheritance生成的ID。
  • 然后通过针对实体指定的@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')

我想那会欺骗;-)