JPA @ OneToMany - & gt; Eltern-Kind-Referenz (Fremdschlüssel)
ich habe eine Frage zum verweisen auf ParentEntities von Kind Entites ir
Wenn ich etwas wie dieses:
Parent.java:
@Entity(name ="Parent")
public class Parent {
@Id
@Generate.....
@Column
private int id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent")
private Set<Child> children;
simple ... getter and setter ...
}
Und die Child.java:
@Entity(name ="Child")
public class Child{
@Id
@Generate....
@Column
private int id;
@ManyToOne
private Parent parent;
... simple getter an setter
}
Werden folgende Tabellen erstellt:
Parent:
int id
Child:
int id
int parent_id (foreign key: parent.id)
Ok, so weit, everthings in Ordnung. Aber wenn es darum geht, mit dieser Referenz von Java, würde ich denken, Sie kann so etwas tun.
@Transactional
public void test() {
Parent parent = new Parent();
Child child = new Child();
Set<Child> children = new HashSet<Child>();
children.add(child);
parent.setChildren(children);
entityManager.persist(parent);
}
führt diese in der Datenbank:
Parent:
id
100
Child
id paren_id
101 100
Aber das ist nicht der Fall, Sie müssen ausdrücklich festlegen, dass ein Elternteil das Kind (die, würde ich denken, der Rahmen könnte wohl von selbst tun).
So was ist wirklich in der Datenbank ist diese:
Parent:
id
100
Child
id paren_id
101 (null)
Ursache habe ich noch nicht festgelegt, den Eltern auf das Kind. Also meine Frage:
Tun, ich habe wirklich zu tun, sth. wie das?
Parent.java:
...
setChildren(Set<Child> children) {
for (Child child : children) {
child.setParent.(this);
}
this.children = children;
}
...
Edit:
Nach dem schnellen Antworten, ich war in der Lage, dieses Problem zu lösen, indem Sie mithilfe der @JoinColumn auf die Referenz-Besitzende Entität. Wenn wir das Beispiel von oben nehmen, ich habe sth. wie diese:
Parent.java:
@Entity(name ="Parent")
public class Parent {
@Id
@Generate.....
@Column
private int id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name= "paren_id")
private Set<Child> children;
simple ... getter and setter ...
}
Und die Child.java:
@Entity(name ="Child")
public class Child{
@Id
@Generate....
@Column
private int id;
... simple getter an setter
}
Nun, wenn wir dies tun:
@Transactional
public void test() {
Parent parent = new Parent();
Child child = new Child();
Set<Child> children = new HashSet<Child>();
children.add(child);
parent.setChildren(children);
entityManager.persist(parent);
}
Die Referenz ist richtig eingestellt, indem die Eltern:
Parent:
id
100
Child
id paren_id
101 100
Danke für die Antworten.
InformationsquelleAutor der Frage Sim0rn | 2012-03-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dass ist eine Strategie, ja.
Auf bi-direktionale Beziehungen gibt es einen "Besitz" und einem "non-owning" - Seite der Beziehung. Weil der besitzenden Seite, in Ihrem Fall ist auf
Child
, müssen Sie die Beziehung, die darin gespeichert werden. Die zugehörige Seite ist in der Regel bestimmt durch, wo Sie angeben@JoinColumn
ist, aber es nicht so Aussehen, wie Sie mithilfe dieser annotation, so ist es wahrscheinlich, wird aus der Tatsache abgeleitet, dass Sie verwendet werdenmappedBy
imParent
annotation.Können Sie Lesen viel mehr zu diesem Thema hier.
InformationsquelleAutor der Antwort beerbajay
Ja, das ist der Fall. JPA hält sich nicht kümmern Konsistenz der entity graph. Vor allem müssen Sie es dem Besitzer der Seite der bidirektionalen Beziehung (in deinem Fall für das übergeordnete Attribut des Kindes).
In JPA 2.0-Spezifikation dieses gesagt wird, mit folgenden Worten:
InformationsquelleAutor der Antwort Mikko Maunu
Immer noch scheint es der Fall zu sein. Im übergeordneten
Entity
können Sie etwas haben, wieum zu vermeiden, sich wiederholenden code für die Einstellung der Kind/Eltern-Beziehung anderswo im code.
InformationsquelleAutor der Antwort pirho
Wir lief in ein problem, beim beibehalten einer einfachen Objekt-graph, wie oben dargestellt. Laufen in der H2 alles funktionieren würde, aber wenn wir ran gegen MySQL "paren_id" in der child-Tabelle (definiert in die @JoinColumn-annotation) war nicht immer bevölkert mit der generierten id der Eltern - auch wenn es eingestellt wurde, eine nicht-null-Spalte mit einem Fremdschlüssel-constraint in der DB.
Würden wir eine Ausnahme wie diese:
Für alle anderen, die vielleicht in dem, was wir schließlich fanden, war, dass wir hatten, um ein anderes Attribut um die
@JoinColumn
um es an die Arbeit:InformationsquelleAutor der Antwort Phil Brock
Wenn ich Sie richtig, nach
EntityManager
, wenn Sie es zum verwalten der Transaktion einfügen, um Ihre habe zu "ihm sagen", dass es anhalten sollte, die Kinder auch. Und Sie sind nicht zu tun, damit "er" nicht weiß, was Sie beibehalten, aber Ihre Eltern die child-Liste ist nicht leer, also "er" findet es richtig, aber der gespeicherte Wert ist null.So sollten Sie überlegen, etwas zu tun:
tun, was Sie wollen mit dem übergeordneten Objekt hier, dann verpflichten und diese Arbeit sollte für ähnliche Fälle zu.
InformationsquelleAutor der Antwort João Rodrigues