2013-03-08 12 views
8

Ich habe 2 Klassen genannt PurchaseList.java und PurchaseListItems.javaHibernate OneToMany, ManyToOne Mapping Giving null

Ich habe PurchaseList in PurchaseListItems

PurchaseList.java

@OneToMany(cascade = CascadeType.ALL) 
@JoinColumn(name="pl_id",referencedColumnName="id") 
private List<PurchaseListItems> purchaseListItems; 

PurchaseListItems.java zur Karte

@ManyToOne 
@JoinColumn(name="pl_id") 
private PurchaseList purchaseListId; 

Alles ist in Ordnung, aber ich bekomme null in pl_id. Bitte sagen Sie, wo ich falsch liege

+0

JPA verwaltet keine bidirektionalen Beziehungen. Sie müssen die umgekehrte Beziehung selbst herstellen. Beachten Sie auch, dass Ihre Zuordnungen zwei unabhängige unidirektionale Beziehungen definieren. Siehe meine Erklärung unten – bennidi

Antwort

5

Ihr Mapping definiert tatsächlich zwei unabhängige unidirektionale Beziehungen. Was Sie wollen, ist ein bidirektionaler relation.The folgenden Code wird die bidirektionale Beziehung

@OneToMany(cascade = CascadeType.ALL, mappedBy = "purchaseListId") 
@JoinColumn(name="pl_id",referencedColumnName="id") 
private List<PurchaseListItems> purchaseListItems; 

Das mappedBy Attribut ist notwendig festzustellen, da es keine Möglichkeit für den Anbieter ist, automatisch festzustellen, dass die angegebenen Beziehungen tatsächlich eine einzige Beziehung bilden. Man könnte den Java-Typ des Instanzmitglieds verwenden, aber was ist, wenn mehrere Elemente desselben Typs vorhanden sind. Und es gibt viele Szenarien, in denen Sie zwei einzelne Beziehungen haben. Beispiel:

OneToMany: Benutzer -> ForumThread (die Fäden vom Benutzer erstellt)

ManyToOne: ForumThread -> Benutzer (. Der Benutzer, der den Faden geschlossen offensichtlich nicht unbedingt derjenige, der den Thread gestartet)

Dies sind zwei unabhängige Beziehungen und müssen als solche behandelt werden. Sie wären ziemlich überrascht, wenn Ihre Persistenz nur eine bidirektionale Beziehung daraus hervorbringen würde, nur weil die Typen und die Multiplizität übereinstimmen.

Beachten Sie auch, dass bidirektionale Beziehungen nicht automatisch von einem JPA-Provider verwaltet werden, dh die inverse Seite wird nicht automatisch in Ihrem Objektmodell und somit nicht in der db aktualisiert/gesetzt. Das musst du selbst machen. Übrigens, in all meinen Projekten waren bidirektionale Beziehungen eine Nervensäge und ich denke, es ist ratsam, sie zu vermeiden.

+6

Mit Hibernate4 (nicht sicher über vorherige ver) mappedby und JoinColumn können nicht zusammen verwendet werden. – Chandru

+0

Ich habe die gleiche Erfahrung wie https://stackoverflow.com/users/1047493/bennidi. Wenn ich bidirektionale Beziehungen vermeiden und alles "manuell" holen werde. Ich war zwei mal schneller fertig. – hariprasad

0

Die Jpa-Spezifikation sieht gut aus, aber überprüfen Sie, ob Sie in der Datenbank eine gültige Eltern-Kind-Beziehung angegeben haben. Wenn es keine Referenz gibt, wird NULL zurückgegeben.

0

versuchen, diese

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "purchaseListId") 
0

Überprüfen Sie, ob Sie purchaseListId mit gültiger Wert (a erstellt PurchaseList Instanz) besiedelt haben, wenn Sie einen PurchaseListItems Wert zu schaffen.

Es ist besser, verwenden mappedBy wie unten Code n-Seite zu lassen, um die Beziehung zu maintian.

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "purchaseListId") 
@JoinColumn(name="pl_id",referencedColumnName="id") 
private List<PurchaseListItems> purchaseListItems; 
+0

Nein, es funktioniert nicht Henry, was Sie oben gesagt haben. Ich vermisse etwas, was ich nicht weiß. –

+0

@sainath Können Sie erklären, was Sie mit "Alles ist gut, aber ich bin null in pl_id."? Sie meinen, pl_id ist null in der Datenbank oder in Ihrer geladenen PurchaseListItems-Instanz? –

+0

In der Datenbank zum Zeitpunkt des Einfügens muss es die ID von Käufe nehmen und es muss pl-id einfügen. Aber stattdessen spart es Null. –

0
for(PurchaseListItems item:purchaseListItemsList) 
item.purchaseListId(PurchaseList); 

Dies ist, was ich verpasst, wenn ich ein Objekt erschaffe.

Thnaks für Ihre Antworten

0
  1. Die @JoinColumn Anmerkung auf der @ManyToOne Seite der Beziehung gehört - aber nicht auf der @OneToMany Seite - nehmen Sie sich vom @OneToMany Seite.

  2. Cascade wird verwendet, um DELETE/READ/UPDATE-Operationen zu kaskadieren, aber es füllt nicht automatisch die ID-Spalte auf der "untergeordneten" Seite eines Fremdschlüssels. Tatsächlich füllt es die Java-Verweise auf Objekte auf beiden Seiten der FK-Beziehung nicht auf. Sie müssen Beziehungsdaten auf beiden Seiten bidirektionaler Beziehungen manuell einrichten:

    myPurchaseListItem.setPurchaseList (myPurchaseList);
    myPurchaseList.setPurchaseListItem (myPurchaseListItem);

    Von der JPA 2 spec:

    bidirektionale Beziehungen zwischen verwalteten Einheiten beibehalten durch die besitzende Seite gehalten Referenzen der Beziehung werden basierend auf. Es liegt in der Verantwortung des Entwicklers, dass die auf der besitzenden Seite gehaltenen und die auf der inversen Seite gespeicherten Referenzen im Speicher bei jeder Änderung konsistent bleiben. Im Falle unidirektionaler Eins-zu-Eins und Eins-zu-Viele-Beziehungen ist der Entwickler dafür verantwortlich, sicherzustellen, dass die Semantik der Beziehungen eingehalten wird.[29]

    Es ist besonders wichtig sicherzustellen, dass Änderungen an der inversen Seite einer Beziehung zu entsprechenden Aktualisierungen auf der besitzenden Seite führen, um sicherzustellen, dass die Änderungen nicht verloren gehen, wenn sie mit der Datenbank synchronisiert werden.

1

Aus irgendeinem Grund kartiert durch nicht mit Postgres SQL und Hibernate4 für mich arbeiten

Below-Mapping gearbeitet

PurchaseList.java

@OneToMany(cascade = CascadeType.ALL) 
@JoinColumn(name="pl_id",nullable=false) 
private List<PurchaseListItems> purchaseListItems; 

PurchaseListItems.java

@ManyToOne 
@JoinColumn(name="pl_id", nullable=false,insertable=false,updatable=false) 
private PurchaseList purchaseListId; 

Hinweis: Sie müssen die Identität oder explizit die Sequenz für ID-Spalten für Postgres erwähnen.

@GeneratedValue(strategy=GenerationType.IDENTITY) 
+0

In der Tabelle wird der Join-Spaltenwert aktualisiert, aber im Entitätsobjekt bekomme ich auch den Wert als Null –

Verwandte Themen