簡體   English   中英

JPA復合鍵+序列

[英]JPA Composite Key + Sequence

是否可以在普通的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的子實體,該復合PK包括來自父級的生成的Id以及另一列。

  • 為子實體提供@ManyToOne關系,以便它在FK列中繼承生成的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')

我想那會欺騙;-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM