6


Ich habe mit Hibernate arbeiten, und ich bin nicht ganz sicher, wie dieses Problem zu lösen, ich habe 2 Tabellen mit einer 1..n Beziehung wie folgt aus:
Hibernate Fremdschlüssel mit einem Teil des zusammengesetzten Primärschlüssel

 
------- 
TABLE_A 
------- 
col_b (pk) 
col_c (pk) 
[other fields] 

------- 
TABLE_B 
------- 
col_a (pk) 
col_b (pk) (fk TABLE_A.col_b) 
col_c (fk TABLE_A.col_c) 
[other fields] 

Wie kann ich das mit Hibernate schaffen?

Ich habe keine Ahnung, wie man einen Fremdschlüssel deklariert, der einen Teil des Primärschlüssels enthalten würde.

Mein Datenbankschema wird aus dem Hibernate-Modell generiert.

+1

Wenn Sie den Winterschlaf kämpfen wollen ... gehen Sie voran und verwenden Sie zusammengesetzte Schlüssel. Wenn Sie ein viel einfacheres Leben wünschen, stellen Sie sicher, dass jede Tabelle eine einzelne Primärschlüsselspalte hat. Vertrauen Sie mir, es ist den Kampf nicht wert ... es ist ein Kampf, der Sie viele Stunden in der Zukunft kosten wird –

+0

Was meinen Sie mit "Teil des Primärschlüssels"? Zusammengesetzte Primärschlüssel in Hibernate sind ziemlich einfach, aber Sie sollten nicht versuchen, dies zu verkomplizieren, indem Sie versuchen, nur einen Teil davon zu verwenden. Grundsätzlich benötigen Sie eine zusammengesetzte Schlüsselklasse. Es gibt eine Antwort hier mit allen grundlegenden Details: http://stackoverflow.com/questions/3585034/how-to-map-a-composite-key-with-hibernate – Karolis

+0

Es gibt eine ziemlich gründliche Antwort hier: http: // stackoverflow .com/a/3588400/3166303 – leeor

Antwort

5

Ich habe zwei Lösungen für dieses Problem gefunden.

Die erste ist eher ein Workaround und ist nicht so sauber wie die zweite.

Definieren den Primärschlüssel der B Einheit als zusammengesetzter Schlüssel enthält col_a, col_b und col_c und was man für den Primärschlüssel in erster Linie sein, definiert als eindeutige Einschränkung. Der Nachteil ist, dass die Spalte col_c nicht wirklich konzeptuell Teil des Primärschlüssels ist.

@Entity 
class A { 
    @Id 
    private int b; 
    @Id 
    private int c; 
} 

@Entity 
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = { "a", "b" }) }) 
class B { 
    @Id 
    private int a; 

    @Id 
    @ManyToOne(optional = false) 
    @JoinColumns(value = { 
      @JoinColumn(name = "b", referencedColumnName = "b"), 
      @JoinColumn(name = "c", referencedColumnName = "c") }) 
    private A entityA; 
} 

Die zweite benutzt @EmbeddedId und @MapsId Anmerkungen und tut genau das, was ich am Anfang zu tun wollte.

0

Jaggers zweite Lösung, die meine erste Reaktion ist, mit @EmbededId und @MapsId. Das Folgende ist ein anderer Weg, der auf seiner zweiten Lösung basiert, aber ohne @MapsId zu verwenden. `

@Entity 
class A { 
    @Id 
    private int b; 
    @Id 
    private int c; 
} 

@Embeddable 
class BKey { 
    private int a; 
    private int b; 
} 

@Entity 
class B { 
    @EmbeddedId 
    private BKey primaryKey; 

    @ManyToOne(optional = false) 
    @JoinColumns(value = { 
      @JoinColumn(name = "b", referencedColumnName = "b", insertable= false, updatable= false), 
      @JoinColumn(name = "c", referencedColumnName = "c") },) 
    private A entityA; 
} 
+0

Dies funktioniert nicht und endet mit einer Ausnahme 'org.hibernate.AnnotationException: Mischen von einfügbaren und nicht einfügbaren Spalten in einer Eigenschaft ist nicht erlaubt 'Es gibt einen Hibernate [bug] (https://hibernate.atlassian.net/browse)/HHH-6221) dafür. – Jagger