[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-616?page=all ]
Steve Ebersole updated HHH-616:
-------------------------------
Fix Version: entity-modes
(was: 3.2.2)
replicate() with a bidirectional relationship fails (dom4j)
-----------------------------------------------------------
Key: HHH-616
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-616
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.0.5
Environment: Hibernate 3.0.5; MySQL 4.1.12
Reporter: David Tashima
Assignee: Gavin King
Fix For: entity-modes
Attachments: test.zip, test3.zip
Here is the original forum post:
http://forum.hibernate.org/viewtopic.php?t=943520
Basically, I am trying to transfer stuff from one DB to another via the Dom4j session. I
create an XML document from the source DB and then I am using session.replicate() on the
receiving end to instantiate the new objects from that XML document.
It works for simple objects, but when I have a bidirectional reference, it is unable to
.replicate() the pair of objects, even if I try to commit() them all in the same
transaction.
I have created a simple model to reproduce this.
Mapping document:
<hibernate-mapping
package="data">
<class name="Foo"
table="foo"
>
<id name="id"
node="@id"
type="string"
unsaved-value="null"
column="foo_id" >
<generator class="uuid" />
</id>
<property
name="prop1"
column="prop1"
type="string"
/>
<many-to-one
name="bar"
column="bar_id"
class="Bar"
not-null="false"
embed-xml="false"
/>
<property
name="index"
column="foo_index"
type="int"
update="true"
/>
</class>
<class name="Bar"
table="bar"
>
<id name="id"
node="@id"
type="string"
unsaved-value="null"
column="bar_id" >
<generator class="uuid" />
</id>
<list
name="foos"
node="foos"
embed-xml="true"
inverse="true"
lazy="false">
<key column="bar_id"/>
<list-index column="foo_index"/>
<one-to-many
class="Foo"
embed-xml="false"
node="foo"
/>
</list>
</class>
</hibernate-mapping>
Reconstitution code:
try
{
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("content.xml"));
Session session = currentSession();
Session s = session.getSession(EntityMode.DOM4J);
Transaction txn = s.beginTransaction();
{
List elems = doc.getRootElement().elements();
Iterator it = elems.iterator();
while(it.hasNext())
{
Element e = (Element)it.next();
log.debug(e.getName());
if(e.getName().equals("Foo"))
s.replicate("data.Foo",e, ReplicationMode.IGNORE);
if(e.getName().equals("Bar"))
s.replicate("data.Bar",e, ReplicationMode.IGNORE);
}
}
txn.commit();
}
catch(DocumentException e)
{
log.error(e);
}
Here is the stack trace:
150 [main] ERROR org.hibernate.util.JDBCExceptionReporter - Cannot add or update a child
row: a foreign key constraint fails
291 [main] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not
synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not insert: [data.Foo]
at org.hibernate.exception.ErrorCodeConverter.convert(ErrorCodeConverter.java:74)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at
org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1869)
at
org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2200)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:46)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:136)
at
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
at
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:329)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
at Test.reconstitute(Test.java:69)
at Test.main(Test.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:78)
Caused by: java.sql.SQLException: Cannot add or update a child row: a foreign key
constraint fails
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2851)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1531)
at
com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1366)
at
com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:952)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1974)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1897)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1758)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at
org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1853)
... 17 more
Exception in thread "main"
org.hibernate.exception.ConstraintViolationException: could not insert: [data.Foo]
at org.hibernate.exception.ErrorCodeConverter.convert(ErrorCodeConverter.java:74)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at
org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1869)
at
org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2200)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:46)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:136)
at
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
at
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:329)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
at Test.reconstitute(Test.java:69)
at Test.main(Test.java:40)
And finally, here is the XML document I am attempting to reconstitute:
<root>
<Foo id="402881e4045ce90c01045ce90f950002">
<prop1>abcd</prop1>
<bar>402881e4045ce90c01045ce90f770001</bar>
<index>0</index>
</Foo>
<Foo id="402881e4045ce90c01045ce90f9f0003">
<prop1>456</prop1>
<bar>402881e4045ce90c01045ce90f770001</bar>
<index>1</index>
</Foo>
<Bar id="402881e4045ce90c01045ce90f770001">
<foos>
<foo>402881e4045ce90c01045ce90f950002</foo>
<foo>402881e4045ce90c01045ce90f9f0003</foo>
</foos>
</Bar>
</root>
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira