Hallo,
ich bin gerade über folgendes Problem gestolpert und wäre für eure Hilfe dankbar:
Ausgangssituation:
1. Ich habe zwei einfache Tabellen: Person und Representatives (Mapping-Files s.u.)
2. Bestandteil des Person-Mapping-Files sind 2 Sets (sinngemäß: "Stellvertreter für..." und "wird vertreten durch...")
3. Auf beiden Spalten der Representatives-Tabelle gibt es einen FK Constraint zur Person-Tabelle
Anwendungsfall:
Ich erstelle eine neue Person und möchte alte Datensätze in der Representatives-Tabelle updaten. Dabei kommt es aber zu einer SQL-Exception (s.u.) da die neue Entität noch nicht geflushed wurde.
Der FlushMode steht auf AUTO.
Nun endlich zu meiner Frage :-)
Mit session.flush() kann ich natürlich vor dem Update einen "Flush" erzwingen, aber ist das wirklich der beste Weg? Muss ich ggf. meine Mapping-Files anpassen, damit automatisch erkannt wird, dass ein Flush erfolgen muss, wenn ein Update auf die Representatives-Tabelle ausgeführt wird und noch frisch erstellte Person-Entitäten an der Session hängen (ohne den FlushMode auf Always zu stellen)?
Vielen Dank und viele Grüße
Micha
Hibernate version: 3.2
Mapping documents:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.server.person.impl.entities">
<class
name="Person"
table="PERSON">
<meta attribute="sync-DAO">true</meta>
<id
name="Id"
type="integer"
column="PERSON_ID">
<generator class="sequence">
<param name="sequence">person_sequence</param>
</generator>
</id>
<set
name="Representatives"
table="REPRESENTATIVES"
cascade="all">
<key>
<column name="TO_REPRESENT" />
</key>
<many-to-many
column="REPRESENTATIVE"
class="Person" />
</set>
<set
name="EmployeesToRepresent"
table="REPRESENTATIVES"
cascade="all">
<key>
<column name="REPRESENTATIVE" />
</key>
<many-to-many
column="TO_REPRESENT"
class="Person" />
</set>
</class>
</hibernate-mapping>
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.server.personl.impl.entities">
<class
name="Representatives"
table="REPRESENTATIVES"
>
<meta attribute="sync-DAO">true</meta>
<composite-id name="Id" class="RepresentativesPK">
<key-many-to-one
name="ToRepresent"
class="Person"
column="TO_REPRESENT"
/>
<key-many-to-one
name="Representative"
class="Person"
column="REPRESENTATIVE"
/>
</composite-id>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
...
Integer oldPersonId = 999;
...
Person entity = createPerson(...);
Integer newPersonId = personDAO.save(entity); // newId = 1412
...
StringBuffer hql = new StringBuffer();
hql.append("update " + Representatives.class.getName() + " rep ");
hql.append("set rep." + Representatives.PROP_ID + ".");
hql.append(RepresentativesPK.PROP_TO_REPRESENT + " = " + newPersonId + " ");
hql.append("where rep." + Representatives.PROP_ID + ".");
hql.append(RepresentativesPK.PROP_TO_REPRESENT + " = " + oldPersonId + " ");
session.createQuery(hql.toString()).executeUpdate();
Full stack trace of any exception that occurs:
DEBUG [main] org.hibernate.util.JDBCExceptionReporter - could not execute update query [update REPRESENTATIVES set TO_REPRESENT=1412 where TO_REPRESENT=999]
java.sql.SQLException: ORA-02291: integrity constraint (X1.PERSON_FK1) violated - parent key not found
Name and version of the database you are using:
Oracle 9i
Debug level Hibernate log excerpt:
DEBUG [main] org.hibernate.event.def.AbstractFlushingEventListener - dirty checking collections
...
DEBUG [main] org.hibernate.pretty.Printer - org.server.person.impl.entities.Person{....Id=1412...}
TRACE [main] org.hibernate.event.def.DefaultAutoFlushEventListener - Dont need to execute flush
...