Hi,
I'm not sure about the following issue - hopefully some of you can help me with the following:
1. There are two simple tables/entities: person and representatives (mapping files below)
2. There are 2 Sets for a person:
- persons representing the current person
- persons to be represented by the current person
3. For both columns of the REPRESENTATIVES table there is a foreign key to the PERSON table
If I create and save a new person entity and some of the old representatives entries should be updated with the new person's id a SQL-Exception is thrown (ParentKey not found - please see below) because the newly created person was not flushed before updating the representatives table. (Please see code snippet below)
FlushMode is AUTO.
Of course, a session.flush() or switching to FlushMode.ALWAYS would solve all my problems, but is this really the best way to tackle this problem? Or is there a possibility to let newly created person entities be auto flushed before a representatives update is executed?
Any help appreciated - thank you
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>
<?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
...
// session.flush(); --> is this really required???
...
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
...