web-dev-qa-db-ja.com

2つの主キーフィールドを持つJPAテーブル

2つのフィールドのみを含むテーブルがあります。テーブルには、これら2つのフィールドで形成された複合PKがあります。

データベースからエンティティBeanを作成するためにNetbeansを使用する場合、エンティティBeanは3つ以上のフィールドを持つ他のテーブルのように自動的に作成されません。

エンティティBeanを自分で作成する必要があると思います。このエンティティBeanを作成するためのベストプラクティスは何ですか? COMPOSITE KEYオブジェクトが含まれている必要がありますか?

11
user2046810

私はNetBeansを使用していないので、マッピングツールについて何も言えません。

複合キーのマッピングには、いくつかのオプションがあります。あなたはできる

  • PKフィールドを持つ個別の @Embeddable オブジェクトを定義し、@EmbeddedId =クラスで @Entity として使用します

    @Embeddable
    public class MyCompositePK { 
        @Column
        private String fieldA;
        @Column
        private String fieldB;
    }
    @Entity 
    public class MyBean { 
        @EmbeddedId
        private MyCompositePK id;
        @Column
        private String fieldC;
    }
    
  • PKフィールドを使用してマップされていないPOJOを定義し、@IdClass@Entity として使用します。

    @Entity
    @IdClass(value=ClassAB.ClassABId.class)
    public class ClassAB implements Serializable {
        private String idA;
        private String idB;
    
        @Id
        @Column(name="ID_A")
        public String getIdA(){ return idA; }
        public void setIdA(String idA){ this.idA = idA; }
    
        @Id
        @Column(name="ID_B")
        public String getIdB(){ return idB; }
        public void setIdB(String idB){ this.idB = idB; }
    
        static class ClassABId implements Serializable {
            private String idA;
            private String idB;
    
            public String getIdA(){ return idA; }
            public void setIdA(String idA){ this.idA = idA; }
    
            public String getIdB(){ return idB; }
            public void setIdB(String idB){ this.idB = idB; }
    
            // implement equals(), hashcode()
        }
    }
    

    この例では、ClassABIdは、便宜上、静的内部クラスです。

これらのオプションは、この質問に対するPascal Thiventの優れた回答でも説明されています。 複合キーをHibernateでマッピングする方法

この関連する質問では、これらのアプローチの違いについて説明します: 使用する注釈:@IdClassまたは@EmbeddedId 。フィールドの宣言が@IdClassアプローチで複製されることに注意してください。

とにかく、2つのクラスを作成する以外の方法はないと思います。それが私がこの質問をした理由です @ IdClassまたは@EmbeddedIdなしの複合PKのみで構成されるクラスのマッピング 。これにはHibernate固有の機能があるようです。

補足として、DB構造を制御できる場合は、複合キーを避けることも検討してください。 そうする理由はいくつかあります

30
Xavi López

@XaviLópezに感謝します。あなたの説明は、@ Tom Andersonによって言及された独自のIdClassとして宣言された私のコードを修正しました。 2つの@Id列を持つ独自のIdClassとして宣言すると、そのエンティティのリストをフェッチするJPAクエリは、結果リストに予期される「n」個のアイテムを返しましたが、そのリストの各アイテムはnullです。ただし、そのサイズ "n"は想定されています。リファクタリングの少ない静的内部クラスに変更すると、正しい結果セットを返すことができます。

私によると、自己参照IdClassは機能しません。なぜなら、自己はすでにエンティティであり、永続コンテキストにある必要があるためです。同じタイプの主キーオブジェクトもある場合、永続化コンテキストには2つの「同一の」オブジェクトがあります。したがって、それは許可されるべきではありません。したがって、自己参照@IdClassは使用しないでください。邪魔にならない主キー型として静的内部クラスを作成します。

0
arunram