-->
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.  [ 1 post ] 
Author Message
 Post subject: Can't import parent/child related data from XML with HB3
PostPosted: Thu May 12, 2005 9:27 am 
Newbie

Joined: Thu May 12, 2005 6:47 am
Posts: 1
I'm trying to import some parent/child related data from an XML file into an Oracle 8i database by use of the 'experimental XML Mapping' feature.

No matter what I'm trying, I do not manage to make the import working (exporting is no problem and works fine). I've been looking around on the net for comparable examples and have read the Hibernate documentation, but haven't found any helpful resource or solution for my problem.

For asking here in the forum, I've prepared an example implementation, which should be easy to understand. The problem I've encountered is, that both the Parent and Child objects have a surrogate identifier generated by a sequence. When saving the Parent to the dom4jSession, a new identifier will be correctly generated for the transient Parent object. Due to cascade="true" also a new identifier will be correctly generated for the related transient Child object. But the Child object will not be automatically related to its Parent object and the foreign key field (Parent parent) of the Child will still be null and causes an exception.

Because of the parent/child mapping and the enabled cascading I had expected, that Hibernate automatically would save the Child to the database and would use the generated identifier of the Parent for the foreign key column (parentid) of the Child. Is this expectation wrong or am I doing something wrong? How can I manage to import parent/child related data from an XML file? I'll be deeply grateful for any help.


Hibernate version: 3.0.3

The DDL statements for the database tables/sequences:

Code:
CREATE SEQUENCE seq_parent
INCREMENT BY 1
START WITH 1
NOCYCLE
;

CREATE SEQUENCE seq_child
INCREMENT BY 1
START WITH 1
NOCYCLE
;

CREATE TABLE parent (
       pid                  NUMBER(19) NOT NULL,
       parentname           VARCHAR2(20) NOT NULL,
       CONSTRAINT idx_pk_parent
              PRIMARY KEY (pid)
)
;

CREATE TABLE child (
       cid                  NUMBER(19) NOT NULL,
       parentid             NUMBER(19) NOT NULL,
       childname            VARCHAR2(20) NOT NULL,
       CONSTRAINT idx_pk_child
              PRIMARY KEY (cid),
       CONSTRAINT cs_parent_child
              FOREIGN KEY (parentid)
                             REFERENCES parent
                             ON DELETE CASCADE
)
;


The content of the xml file which to import:

Code:
<?xml version="1.0" encoding="UTF-8"?>

<exchange>
  <parent>
    <pid></pid>
    <parentname>father</parentname>
    <children>
      <child>
        <cid></cid>
        <childname>son</childname>
        <parent></parent>
      </child>
    </children>
  </parent>
</exchange>


Mapping documents:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping package="parentchild.model">

<class name="Parent" table="PARENT" node="parent">
   <id name="pid"
      column="PID"
      type="long"
   >
      <generator class="native">
         <param name="sequence">seq_parent</param>
      </generator>
   </id>

   <property name="parentname"
      column="PARENTNAME"
      type="string"
      not-null="true"
      length="20"
   />

   <!-- bi-directional one-to-many association to Child -->
   <set name="children"
      lazy="true"
      inverse="true"
      cascade="all"
      embed-xml="true"
   >
      <key column="PARENTID"/>
      <one-to-many class="Child"/>
   </set>
</class>


<class name="Child" table="CHILD" node="child">
   <id name="cid"
      column="CID"
      type="long"
   >
      <generator class="native">
         <param name="sequence">seq_child</param>
      </generator>
   </id>

   <property name="childname"
      type="string"
      column="CHILDNAME"
      not-null="true"
      length="20"
   />

   <!-- bi-directional many-to-one association to Parent -->
   <many-to-one name="parent"
      column="PARENTID"
      class="Parent"
      not-null="true"
      embed-xml="false"
   />
</class>

</hibernate-mapping>


Code for importing:

Code:
Session session = HibernateUtil.getSession();
Session dom4jSession = session.getSession(EntityMode.DOM4J);
HibernateUtil.beginTransaction();

String filename = "parentchild.xml";
File file = new File(filename);
SAXReader reader = new SAXReader();
Document doc = reader.read(file);
List data = doc.selectNodes("/exchange/parent");

Iterator it = data.iterator();
while (it.hasNext()) {
   dom4jSession.save("parentchild.model.Parent", it.next());
}

HibernateUtil.commitTransaction();
HibernateUtil.closeSession();


Debug level Hibernate log excerpt:

Code:
DEBUG AbstractSaveEventListener:409 - transient instance of: parentchild.model.Parent
DEBUG DefaultSaveOrUpdateEventListener:159 - saving transient instance
DEBUG AbstractBatcher:277 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG SQL:311 - select hibernate.seq_parent.nextval from dual
Hibernate: select hibernate.seq_parent.nextval from dual
DEBUG AbstractBatcher:365 - preparing statement
DEBUG SequenceGenerator:87 - Sequence identifier generated: 12
DEBUG AbstractBatcher:285 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG AbstractBatcher:403 - closing statement
DEBUG AbstractSaveEventListener:89 - generated identifier: 12, using strategy: org.hibernate.id.SequenceGenerator
DEBUG AbstractSaveEventListener:132 - saving [parentchild.model.Parent#12]
DEBUG Cascades:836 - processing cascade ACTION_SAVE_UPDATE for: parentchild.model.Parent
DEBUG Cascades:861 - done processing cascade ACTION_SAVE_UPDATE for: parentchild.model.Parent
DEBUG Cascades:836 - processing cascade ACTION_SAVE_UPDATE for: parentchild.model.Parent
DEBUG Cascades:890 - cascade ACTION_SAVE_UPDATE for collection: parentchild.model.Parent.children
DEBUG Cascades:153 - cascading to saveOrUpdate: parentchild.model.Child
DEBUG AbstractSaveEventListener:409 - transient instance of: parentchild.model.Child
DEBUG DefaultSaveOrUpdateEventListener:159 - saving transient instance
DEBUG AbstractBatcher:277 - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG SQL:311 - select hibernate.seq_child.nextval from dual
Hibernate: select hibernate.seq_child.nextval from dual
DEBUG AbstractBatcher:365 - preparing statement
DEBUG SequenceGenerator:87 - Sequence identifier generated: 12
DEBUG AbstractBatcher:285 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG AbstractBatcher:403 - closing statement
DEBUG AbstractSaveEventListener:89 - generated identifier: 12, using strategy: org.hibernate.id.SequenceGenerator
DEBUG AbstractSaveEventListener:132 - saving [parentchild.model.Child#12]
org.hibernate.PropertyValueException: not-null property references a null or transient value: parentchild.model.Child.parent
        at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
        at ...


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

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.