Ich habe zwei einfache Klassen A und B, die sich gegenseitig referenzieren. Dabei handelt es sich nicht um ein bidirektionales Mapping, sondern um zwei unabhängige unidirektionale Mappings. D.h. Jedes dieser Mappings kann gesetzt sein, oder auch nicht.
Bei beiden Mappings ist cascade="all" gesetzt, damit evtl. referenzierte Objekte mit persistiert werden.
Wenn ich jetzt neue zwei Instanzen erzeuge und verlinke und dann z.B. die Instanz von A persistiere, passiert fasst das erwartete, aber es gibt ein Problem.
ClassA classA = new ClassA();
ClassB classB = new ClassB();
classA.setClassB(classB);
classB.setClassA(classA);
session.save(classA);
Hibernate erkennt, dass classA und classB neue noch nicht persistierte Objekte sind. Da cascading eingeschaltet ist, wird erstmal classB persistiert . Dabei wird eine ID für die classB Instanz generiert (landet in ID in Tab. CLASS_B) und landet schliesslich auch als Foreign Key in der CLASS_B_ID Spalte in Tabelle CLASS_A.
Zum Abschluss der Transaktion wird classA persistiert. Wiederum wird eine ID generiert und auch korrekt als ID in CLASS_A gespeichert.
Jetzt das Problem:
Die Spalte CLASS_A_ID in Tabelle CLASS_B bleibt auf NULL.
Mir ist schon klar, dass zum Zeitpunkt als die classB Instanz persistiert wird, die ID von classA noch nicht generiert wurde, aber eigentlich hätte ich erwartet, dass der Cascading Mechanismus dies erkennt und für die fehlenden IDs ein UPDATE hinterherschickt.
Erwarte ich da zuviel oder mache ich irgendetwas falsch?
Das ganze ist ein vereinfachtes Beispiel aus einem reallen Modell, dass Instanzen von drei Klassen erzeugt, diese über mehrere Referenzen hin und her verknüpft und dann schliesslich persistiert. Leider fehlen an einigen Stellen dann die passenden Foreign Keys...
Hibernate version: 2.1.8
Mapping documents:
<class name="ClassA" table="CLASS_A">
<id name="id" column="ID" type="int">
<generator class="native"/>
</id>
<version column="VERSION" name="version" type="int" unsaved-value="null"/>
<many-to-one name="classB" column="CLASS_B_ID" class="ClassB" cascade="all"/>
</class>
Analog dazu Class B:
<class name="ClassB" table="CLASS_B">
<id name="id" column="ID" type="int">
<generator class="native"/>
</id>
<version column="VERSION" name="version" type="int" unsaved-value="null"/>
<many-to-one name="classA" column="CLASS_A_ID" class="ClassA" cascade="all"/>
</class>
Code between sessionFactory.openSession() and session.close():
ClassA classA = new ClassA();
ClassB classB = new ClassB();
classA.setClassB(classB);
classB.setClassA(classA);
session.save(classA);
Name and version of the database you are using: MySQL 4
|