17

プレーンな 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;
    }

    //...
}

applicationentitynativeIdおよびの値はすでに指定しています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 を使用したくありません)。

4

4 に答える 4

3

これはプレーンなJPAでは不可能だと思います。

于 2009-02-24T20:49:43.110 に答える
2

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

JPA仕様から:

11.1.17 GeneratedValue注釈

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

別のシナリオでは、@GeneratedValue を使用する単純な PK (@Id) を持つ親エンティティを持ち、親から生成された Id と別の列を含む複合 PK を持つ子エンティティを持つことができることに注意してください。

  • 子に親エンティティへの @ManyToOne 関係を与えて、生成された ID を FK 列で継承できるようにします。
  • 次に、エンティティに対して指定された @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) { //... }
}
于 2012-10-15T02:16:57.627 に答える
1

この例のように複合主キーを作成しているように見えます。私は自分のデータベースで同様の問題を突きつけていましたが、次のようにSQLを直接呼び出すことができるのではないかと思いました:

select nextval ('hibernate_sequence')

私はそれが不正行為になると思います;-)

于 2009-03-30T15:00:28.873 に答える
1

このようにしてみてください:

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

このようにして、シーケンスを使用する代わりにテーブルを使用できます。

于 2008-10-28T17:00:18.173 に答える