-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: replicate() with a bidirectional relationship fails (dom4j)
PostPosted: Wed Jun 08, 2005 1:19 pm 
Newbie

Joined: Sun Jun 27, 2004 5:05 pm
Posts: 11
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Basically, I'm trying to use the dom4j session to create a data transfer between databases. So, I have an extractor that creates an XML document from a database, and then a have a populator that takes the XML document and replicates() objects in an empty DB.

This works great, except for when I try to populate a pair of classes that have a bidirectional relationship (one-to-many and many-to-one). I get a "java.sql.SQLException: Cannot add or update a child row: a foreign key constraint fails" error message.

Am I going about this the wrong way? Should I be using something besides replicate()?

Hibernate version:
3.0.5

Mapping documents:
Code:
<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>


Code between sessionFactory.openSession() and session.close():
Here is the populator:
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);
        }


Full stack trace of any exception that occurs:
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)
Name and version of the database you are using:
MySQL 4.1.12

The generated SQL (show_sql=true):
0 [main] DEBUG Test - Creating new Hibernate Session: main
10 [main] DEBUG Test - Foo
Hibernate: select foo_id from foo where foo_id =?
70 [main] DEBUG Test - Foo
Hibernate: select foo_id from foo where foo_id =?
70 [main] DEBUG Test - Bar
Hibernate: select bar_id from bar where bar_id =?
Hibernate: insert into foo (prop1, bar_id, foo_index, foo_id) values (?, ?, ?, ?)

-----------
The content.xml document looks like this:
Code:
<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>


It was created using this:
Code:
    private static void createDocument() {
        Session sess;
        sess = currentSession();
        Session s = sess.getSession(EntityMode.DOM4J);

        Document doc = DocumentHelper.createDocument();
        Element root = doc.addElement("root");

        List results = s.createQuery("from Foo foo ").list();
        addResultsToNode(results, root);

        results = s.createQuery("from Bar bar ").list();
        addResultsToNode(results, root);

        OutputFormat format = OutputFormat.createPrettyPrint();
        try
        {
            XMLWriter writer = new XMLWriter(new FileWriter("content.xml"), format);
            writer.write(doc);
            writer.close();
        }  catch(IOException ioe) {    }

    }

    private static void addResultsToNode(List results, Element root)
    {
        for (Iterator i = results.iterator(); i.hasNext();) {
            Element e = (Element) i.next();
            if(e != null)
            {
                log.debug("e: "+e.toString());
                root.add(e);
            }
        }
    }


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 3:02 am 
Beginner
Beginner

Joined: Thu Jun 02, 2005 5:09 am
Posts: 22
AFAIK, bi-directional List associations aren't supported when using inverse="true" on the parent-side: Hibernate will ignore changes made only to the collection, so re-ordening of your collection elements won't result in updates of the index column of the row representing these elements.
I did see two pages mentioning new support for these kind of relations in Hibernate 3, but I have some questions about this support myself (see http://forum.hibernate.org/viewtopic.php?t=943384, the text also refers to the two relevant pages on the Hibernate site).

Joris


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 13, 2005 6:40 pm 
Newbie

Joined: Sun Jun 27, 2004 5:05 pm
Posts: 11
Hmmm, good idea, but removing inverse="true" didn't seem to have any effect.

I really think there is an issue in the dom4j session.replicate() - it's not a problem just save()ing objects - it's the replication that gets messed up. (I would think that it it verifying foreign keys that aren't there yet).

-Dave


Top
 Profile  
 
 Post subject: circular
PostPosted: Wed Jun 15, 2005 6:17 pm 
Newbie

Joined: Fri Mar 04, 2005 9:33 pm
Posts: 3
I think you cant have the inverse like his suggestion as this would form a curcular reference which i think still an xml paradox when redering a bidirectional relation in other words try without a biderectional

_________________
Mike


Top
 Profile  
 
 Post subject: Re: replicate() with a bidirectional relationship fails (dom4j)
PostPosted: Mon Aug 02, 2010 3:14 am 
Newbie

Joined: Mon Aug 02, 2010 3:11 am
Posts: 1
hmm.... really good idea but as the Mr. tash you have to remore "true" from this. and after this it may be goona useful to you.

Thanks!!!

_________________
relationship advice


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.