質問

単純な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;
    }

    //...
}

すでに 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ではこれは不可能だと思います。

他のヒント

JPA 2仕様では、複合PKに@GeneratedValueを使用することは指定されていません。

JPA仕様から:

  

11.1.17 GeneratedValueアノテーション

     

GeneratedValueアノテーションは、   主キーの値の生成戦略。の   GeneratedValue注釈は、主キープロパティに適用されるか、   Idと組み合わせたエンティティまたはマッピングされたスーパークラスのフィールド   注釈。[97] GeneratedValueアノテーションの使用は   単純な主キーをサポートする必要があります。の使用   GeneratedValue注釈は、派生主キーではサポートされていません。

異なるシナリオでは、@ GeneratedValueを使用する単純なPK(@Id)を持つ親エンティティがあり、その後、親から生成されたIDを含む複合PKを持つ子エンティティを持つことができます。別の列。

  • FK列で生成されたIDを継承するように、子に親エンティティへの@ManyToOne関係を与えます。
  • 次に、エンティティに対して指定された@IdClassと、エンティティ内の2つの@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を呼び出すことができるのではないかと思った:

nextval( 'hibernate_sequence')を選択します

それは不正行為だと思う;-)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top