2013-02-06 17 views
10

Ich habe eine Tabelle, die nur 2 Felder enthält. Die Tabelle hat eine zusammengesetzte PK, die durch diese zwei Felder gebildet wird.JPA-Tabelle mit 2 Primärschlüsselfeldern

Bei der Verwendung von NetBeans zum Erstellen von EntityBeans aus der Datenbank wird das EntityBean nicht wie andere Tabellen mit mehr als zwei Feldern automatisch erstellt.

Also ich denke, ich muss die Entity Bean selbst erstellen. Was ist die beste Vorgehensweise zum Erstellen dieser Entity-Bean? Muss es COMPOSITE KEY Objekt enthalten oder nicht?

+0

@ Xavi López: Sie bilden die PK zusammen. – user2046810

Antwort

27

Ich benutze NetBeans nicht, also kann ich nicht wirklich etwas über seine Mapping-Tools sagen.

Für die Zuordnung eines zusammengesetzten Schlüssels gibt es eine Reihe von Optionen. Sie können

  • definieren einen separaten @Embeddable Objekt mit den PK Felder und verwenden Sie es als @EmbeddedId in Ihrer @Entity Klasse

    @Embeddable 
    public class MyCompositePK { 
        @Column 
        private String fieldA; 
        @Column 
        private String fieldB; 
    } 
    @Entity 
    public class MyBean { 
        @EmbeddedId 
        private MyCompositePK id; 
        @Column 
        private String fieldC; 
    } 
    
  • definieren einen nicht abgebildet POJO mit den PK Felder und verwenden Sie es als @IdClass in der @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() 
        } 
    } 
    

    In diesem Beispiel ClassABId ist eine statische innere Klasse nur für die Bequemlichkeit.

Diese Optionen werden auch in Pascal Thivent die ausgezeichnete Antwort auf diese Frage erklärt: How to map a composite key with Hibernate?.

Diese verwandte Frage diskutiert Unterschiede zwischen diesen Ansätzen: Which anotation should I use: @IdClass or @EmbeddedId. Beachten Sie, dass die Deklaration der Felder mit der Methode @IdClass dupliziert wird.

Wie auch immer, ich glaube nicht, dass es eine Alternative zum Erstellen von zwei Klassen gibt. Deshalb habe ich diese Frage gestellt: Mapping a class that consists only of a composite PK without @IdClass or @EmbeddedId. Es scheint, dass es eine Hibernate-spezifische Funktion dafür gibt.

Als Nebenbemerkung, wenn Sie Kontrolle über die DB-Struktur haben, könnten Sie auch in Betracht ziehen, zusammengesetzte Schlüssel zu vermeiden. There are some reasons to do so.

+2

Wenn das Objekt nur die zwei Primärschlüsselfelder enthält, kann es eine eigene 'IdClass' sein? –

+1

@ Tomanderson Das ist interessant. Das habe ich nie versucht. Es scheint, dass [jemand tat] (https://forum.hibernate.org/viewtopic.php?p=2419264), ohne Erfolg.Die Spezifikation scheint darüber nicht zu sprechen. Könnte von der Implementierung abhängen. –

+1

@TomAnderson: Ich denke nicht, weil die ID-Klasse seine equals() -Methode basierend nur auf den zusammengesetzten Schlüsselwerten implementieren muss. –

0

Danke @ XaviLópez. Deine Erklärung hat meinen Code korrigiert, der als eigene IdClass deklariert wurde, die von @Tom Anderson erwähnt wurde. Wenn ich eine eigene IdClass mit zwei @Id-Spalten deklarierte, gab eine JPA-Abfrage, die eine Liste dieser Entität abruft, erwartete "n" -Elemente in der Ergebnisliste zurück, aber jedes Element in dieser Liste ist null. Aber diese Größe "n" wird erwartet. Nach dem Wechsel in die statische innere Klasse, die weniger refactoring ist, kann sie den richtigen Ergebnissatz zurückgeben.

Nach meiner Meinung: Selbstreferenzierung IdClass funktioniert nicht, weil das Selbst bereits eine Entität ist und das im Persistenzkontext sein muss. Wenn ich auch ein Primärschlüsselobjekt desselben Typs habe, dann gibt es im Persistenzkontext zwei "identische" Objekte. Also sollte es nicht erlaubt sein. Daher sollten wir keine Selbstreferenzierung @IdClass verwenden. Erstellen Sie eine statische innere Klasse als Primärschlüsseltyp, die weniger aufdringlich ist.