-->
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.  [ 10 posts ] 
Author Message
 Post subject: parent child relationshp
PostPosted: Tue Oct 11, 2005 7:38 am 
Newbie

Joined: Tue Oct 11, 2005 6:47 am
Posts: 5
Hibernate version:2.1

SQL Server


Let me start by confessing that I am relatievly new to Hybernate. I have a typical parent child relationship scnario which we are thinking of persisting using hibernate.

the scenario: The entities we have here are 1. Form - corresponds to form table in database 2. Page - which corresponds to page table 3. Section - which corresponds to section table.

What I Have: FormPOJO with form_id as primary key(increment),it's properties and a collection for holding Page objects. PagePOJO with page_id as primary key(increment),form_id as foreign key,it's properties and a collection for Section objects. SectionPOJO with secion_id as primary_key and page_id as foreign key.

What I am trying to do: I am trying to persist the entire Form(consisting of Pages which internally contains Sections) using a single save. It is happening but I am not able to set the foreign keys(e.g form_id in Page) on the fly. Since the primary keys for the parent tables are also created on the fly by the id generator(which acts as the foreign key for the child tables), I am not too sure whether I could do it the way I am doing. Or do I have to save the parent first, retreive it's id , set it explicitly in the child and explicitly save the child?

Below attached are my mappings:

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

<class name="com.intelliworks.dynamicformbuilder.vo.FormPOJO" table="form">

<id name="formId" column="form_id" type="java.lang.Long" unsaved-value="null" >
<generator class="identity"/>
</id>
<property name="instanceId" column="instance_id" type="java.lang.Long"/>
<property name="name" column="name" type="java.lang.String"/>
<property name="description" column="description" type="java.lang.String"/>
<property name="styleId" column="style_id" type="java.lang.Long"/>
<property name="https" column="https" type="java.lang.String"/>
<property name="pages" column="pages" type="java.lang.Long"/>

<set name="page" table="page" lazy="true" inverse="true" cascade="all-delete-orphan">
<key column="form_id" ></key>
<one-to-many class="com.intelliworks.dynamicformbuilder.vo.PagePOJO" />
</set>
</class>

</hibernate-mapping>

pagePOJO.hbm.xml
-----------------------
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.intelliworks.dynamicformbuilder.vo.PagePOJO" table="page">

<id name="pageId" column="page_id" type="java.lang.Long" unsaved-value="null" >
<generator class="identity"/>
</id>

<property name="formId" column="form_id" type="java.lang.Long" formula=""/>
<property name="name" column="name" type="java.lang.String"/>
<property name="seqNo" column="seq_no" type="java.lang.Long"/>

<many-to-one name="parent" column="form_id" insert="false" update="false" not-null="true"/>

<!--<set name="section" table="sections" lazy="true">
<key column="page_id" ></key>
<one-to-many class="SectionPOJO" />
</set>-->
</class>

</hibernate-mapping>

Below pasted is my code:

public class DAHelper
{
/**
* Class Level Instance Variable
*/

/**
* Adds the specified Employee into the
* database.
* @return Long
*/
public boolean addForm(FormPOJO form)
{
try
{
/**
* load the hibernate configuartion file and obtain the sessionfactory object
*/
SessionFactory sessionFact = new Configuration().configure().buildSessionFactory();
System.out.println("SessionFactory saved~~~~~"+sessionFact);
// retreive the hibernate session object for updating the records to the table
Session sess = sessionFact.openSession();
Transaction trx = sess.beginTransaction();

System.out.println("form => " + form.toString());
//save the POJO object to hibernate session
sess.save(form);

sess.flush();

//commit the transaction.
trx.commit();

//close the hibernate session object.
sess.close();

}
catch(Exception ex)
{
ex.printStackTrace();
}

return true;
}


public static void main(String x[])
{
DAHelper daHelper = new DAHelper();

PagePOJO page1 = new PagePOJO();
//page.setFormId(new Long(8));
page1.setName("form_page_"+Math.floor(Math.random()*100));
page1.setSeqNo(new Long(1));

PagePOJO page2 = new PagePOJO();
//page.setPageId(new Long(1));
page2.setName("form_page_"+Math.floor(Math.random()*100));
page2.setSeqNo(new Long(2));

FormPOJO form = new FormPOJO();

form.setName("test_form_"+Math.floor(Math.random()*100));
form.setDescription("test description");
form.setHttps("N");
form.setInstanceId(new Long(1));
form.setPages(new Long(1));
form.setStyleId(new Long(16));

form.getPage().add(page1);
form.getPage().add(page2);

daHelper.addForm(form);
}
}


Thanx in advance for whatever suggestions you have on the same.



Top
 Profile  
 
 Post subject: Re:
PostPosted: Mon Oct 17, 2005 3:32 am 
Newbie

Joined: Tue Oct 11, 2005 6:47 am
Posts: 5
I am still stuck with the same problem which I guess many of you would have encountered and solved. Let me try to explain my problem a little more..

I have a Parent class corresponding to a DB table and its Child class corresponding to a DB table. Both have their on primary keys generated with the help of identity generator(Since i am using MS SQL Server).

My problem is how to inform Hibernate using the xml mappings that while inserting into the Child table, it should use the primary key generated at the time of inserting the parent(parent_id) as the value for a property, say foreign_id(in the Child table)?

regards
martmd


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 17, 2005 4:15 am 
Beginner
Beginner

Joined: Wed Oct 12, 2005 8:52 am
Posts: 23
If you don't want to keep the original foreign keys/ids, use the :
Quote:
unsaved-value
tag in the ID section of the hbm file.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 17, 2005 4:33 am 
Newbie

Joined: Tue Oct 11, 2005 6:47 am
Posts: 5
Thanx for the suggestion...

But I need the ids and the generated values..


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 17, 2005 5:02 am 
Beginner
Beginner

Joined: Wed Oct 12, 2005 8:52 am
Posts: 23
OK, one thing you could do:
If you are using Hibernate 3, use Session.replicate() instead of saveOrUpdate()/save(). E.g

Code:
session.replicate(object,ReplicationMode.OVERWRITE);


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 17, 2005 1:16 pm 
Beginner
Beginner

Joined: Thu Jan 22, 2004 8:22 pm
Posts: 48
I have a very similar mapping in one of my systems. I beleive your problems resolves around the fact that you have the form_id column mapped twice. Once as a attribute and once as a relationship. You should remove the property entry in page for form_id and just leave the many to one for parent.

Also, since you have a unsaved value specified for the id on each class and apparently the column is defined in the database as identity you should never need to explicitly assign the id to any of these objects.

I also think because of the way you have inverse set you need to make sure that the pages get added to the forms page set and that the parent property of the pages get's set before you issue the session.save call.

Hope that helps some.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 18, 2005 4:58 am 
Newbie

Joined: Tue Oct 11, 2005 6:47 am
Posts: 5
I tried it but didnt work..below pasted is my Page xml with the formId commented

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.intelliworks.dynamicformbuilder.vo.PagePOJO" table="page">

<id name="pageId" column="page_id" type="java.lang.Long" unsaved-value="null" >
<generator class="identity"/>
</id>

<!--<property name="formId" column="form_id" type="java.lang.Long"/>-->
<property name="name" column="name" type="java.lang.String"/>
<property name="seqNo" column="seq_no" type="java.lang.Long"/>

<many-to-one name="parent" column="form_id" insert="false" update="false" not-null="true"/>

<!--<set name="section" table="sections" lazy="false" inverse="true" cascade="all-delete-orphan">
<key column="page_id" ></key>
<one-to-many class="com.intelliworks.dynamicformbuilder.vo.SectionPOJO" />
</set>-->


</class>

</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 18, 2005 7:07 am 
Beginner
Beginner

Joined: Thu Jan 22, 2004 8:22 pm
Posts: 48
Did you also change things so that when a page is added to a form that the parent attribute of the page get's set properly?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 3:21 pm 
Newbie

Joined: Wed Sep 14, 2005 9:15 am
Posts: 12
Location: St. Louis
I too, have been facing the same issue... My parent's Primary Key is generated automatically by the database upon record insert (I'm using MySQL). This same Primary Key makes up the Composite Key of each Child record. The other half of the Composite Key is passed via the JSP - so I have half of the Composite Key.

When I call save, passing in the entire object graph, Hibernate throws an exception indicating that part of the Child record's Composite Key cannot be null, which I understand completely, however, I thought Hibernate would automactically pick up the other half of the Composite Key (i.e., the Parent's Primary Key)??

My only solution was to save the Parent record first, and then save each Child record, manually setting the Parent's Primary Key to each Child record before calling save. I do not like this approach, but it's the only solution I could come up with. I tried a bunch of other stuff with the .hbm docs, but that still didn't do the trick... So if you find anything out, please let me know.

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 11:58 pm 
Newbie

Joined: Tue Oct 11, 2005 6:47 am
Posts: 5
Hi,

I have seen somethings about composite keys in the hibernate ref manual, which I thought could have solved your issue. But I am sure you would have explored those possibilities. I also did the same thing as you did. The only difference is, First: I saved my parent class first with its children - hibernate executed all the insert statements(for parent and children). It didnt throw any exception since the parent id in my case is a foreign key and not a composite key.

Second: From the saved parent, I retreived the child set and added the parent id to them - Hibernate executed the corresponding update satements on the child tables(synchronisation). This is not recomended in terms of performance since on each child table, there is an insert and an update happening. But i haven't found a proper solution to it.

The worst thing here is that in my case the depth of composition is 6+ (i.e parent->child->grandchild-> ... )and I have many nested while loops in my code which I fear will become a performance bottleneck from the java perspective too.

Waiting for a better solution..

martmd


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 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.