-->
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.  [ 13 posts ] 
Author Message
 Post subject: one-to-many - automatically set parent property in childs
PostPosted: Tue Nov 14, 2006 10:51 am 
Newbie

Joined: Fri Sep 29, 2006 6:52 am
Posts: 17
I have a one-to-many relation between Parent and a list of Childs:

Code:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="Test.Parent, Test">
      <id name="Id" access="nosetter.lowercase-underscore">
        <generator class="native" />
      </id>
      <list name="Childs" cascade="all">
        <key column="Parent" />
        <index column="`Position`" />
        <one-to-many class="Test.Child, Test"/>
      </list>
    </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Test.Child, Test">
    <id name="Id" access="nosetter.lowercase-underscore">
      <generator class="native" />
    </id>
    <many-to-one name="Parent" />
  </class>
</hibernate-mapping>


Now I do this:

Code:
Parent parent = new Parent();
Child child = new Child();
parent.Childs.Add(child);
session.Save(parent);
Assert.IsNotNull(child.Parent);


But it fails. Saving the parent correctly saves the childs as well (cascading). And when I load the child, it's Parent property is correctly set.

But I would expect Nhibernate to set the Parent property on the child objects saved in the session immediately. Is there a way to do this?

Currently I work around by using a Parent.Add(Child child), which adds the child and sets it's Parent property. I'm just wondering if there's a solution on the nhibernate level.

Tobias


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 8:10 pm 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
Its your responsability to set up the Parent property as well:

Code:
child.Parent=parent;


HTH,
Radu


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 15, 2006 12:53 am 
Senior
Senior

Joined: Mon Aug 21, 2006 9:18 am
Posts: 179
Ayende's Generics collections tried to alleviate some of this by creating custom collections that accept delegates for the .Add and .Remove methods of the parent. This collection is deprecated tho because NHibernate now accomodates Generics.
Best practice is to provide a Parent.Add(Child child) method that handles this for you.

_________________
If this helped...please remember to rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 15, 2006 8:47 am 
Newbie

Joined: Fri Sep 29, 2006 6:52 am
Posts: 17
Thanks!

So I will have to stick with Parent.Add() for now. But I still think, it would be nice, if NHibernate could do this for me automatically on Save().

I tried to find a way to modifiy NHibernate myself, but at least there seems to be no trivial solution and Sergey doesn't want Nhibernate to modify any properties.

Tobias


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 11, 2007 12:26 pm 
Newbie

Joined: Wed Jan 10, 2007 9:28 am
Posts: 6
OK, that's an interesting point !!

I have a question about xml import. I have the same problem.

My s database schema is : Father:1--------n:Son


my xml file look like that :
Code:
<peres ....>
   <pere ...>
      <enfants>
         <enfant ...>
         <enfant ...>
      </enfants>
   </pere>
   <pere ...>
      <enfants>
         <enfant ...>
         <enfant ...>
      </enfants>
   </pere>
</peres>



So, when I import a Father Element in the database, it import the father and all the Sons related with the father in the Database, but it abort because of the FatherID in the Sons is not seted.
So in the DataBase, Sons point on a bad father or an inexisting father

shouldn't hibernate to set the father id in the son ?

Do you think that's the same problem as you with the hibernate objects?

thanks


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 11, 2007 7:02 pm 
Beginner
Beginner

Joined: Mon Jan 08, 2007 11:59 pm
Posts: 31
The book "Hibernate in Action" clearly says that you have to set both the sides of the relation for it to save correctly. The concept here is that NH is providing you transparent persistence, think how you would create the relation if NH were not there, you would set both the side of the relation, right?

So you need to set both the side of the relation in code and NH will set up the same in the DB. Changing this behavior in NH in not in the spirit of the original thinking of the designers.

Regards
Job Samuel.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 11, 2007 7:43 pm 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
Why should calling Save set the properties in the child? Think about what this would mean. The Parent property is valid after the Save, but not before. You would have to know if something has been saved or not to know whether you can access the property. This would not make much sense.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 5:24 am 
Newbie

Joined: Wed Jan 10, 2007 9:28 am
Posts: 6
thanks for answers.

Quote:
Why should calling Save set the properties in the child?


I can't set the property in the shild.

I'm not trying to import hibernate objects, but an xml file, so I can't set any property in the child.
When I import hibernate objects, I add children into the father and I set the father in the children. That's ok.

During the import of xml file, hibernate is looking for "pere" elements and, thanks to the mapping file, can import the father in db, then children. But it don't set the FATHER_ID in the Child
I never can access the data to update the FATHER_ID in the child, because the import doesn't use hibernate object, so I can't set the FATHER_ID property. That's my problem !!

I thought that hibernate do it automatically.


Look at my code:

Code:
Session dom4jSession = (Session) currentSession.getSession(EntityMode.DOM4J);
Transaction transaction = currentSession.beginTransaction();

// Read document with DOM4J
SAXReader saxReader = new SAXReader();
File file = new File(xmlFilePath);
org.dom4j.Document xmldb = saxReader.read(file);

// Get all "pere" elements to import
java.util.List l = xmldb.getRootElement().elements("pere");

Iterator it = l.iterator();
while(it.hasNext()){
   Object next = it.next();
   dom4jSession.save("chemin.pere", next);
}
transaction.commit();
currentSession.close();



Then the Hibernate trace :

// get sequences in db for the father en the child
Hibernate: select SEQ_PERE_ID.nextval from dual
Hibernate: select SEQ_ENFANT_ID.nextval from dual

// Insertin the db: during fluch(in the save method) first the father, then the child
Hibernate: insert into PERE (champ1,champ2,...) values (?, ?, ...)
Hibernate: insert into ENFANT (champ1,champ2,...) values (?, ?, ...)
but for the child : ---> MyProject.FK_TEMPLATE) violated - parent key not found


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 7:38 am 
Contributor
Contributor

Joined: Sat Sep 24, 2005 11:25 am
Posts: 198
You may need to play with Inverse on this, see if it gets you what you want.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 9:18 am 
Newbie

Joined: Wed Jan 10, 2007 9:28 am
Posts: 6
Hy ! thx
I have also try playing with inverse.

But for many-to-one relation, there is no choice :
we have to set Inverse="true" to the side of the child

When I set inverse="true" in the other side(father), I get an mapping exception

someone have another idee ?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 2:12 pm 
Regular
Regular

Joined: Fri Feb 03, 2006 5:28 pm
Posts: 73
Location: Québec, QC, Canada
mnichols wrote:
Ayende's Generics collections tried to alleviate some of this by creating custom collections that accept delegates for the .Add and .Remove methods of the parent. This collection is deprecated tho because NHibernate now accomodates Generics.
Best practice is to provide a Parent.Add(Child child) method that handles this for you.


Is there a way to prevent user from doing

Parents.childs.add(child) directly against the collection and forcing them to use the Parent.Add(Child child) method?

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 7:39 pm 
Contributor
Contributor

Joined: Sat Sep 24, 2005 11:25 am
Posts: 198
Returning a read only version for the Get is one way.
Or returning a custom interface that doesn't have an Add/Remove method.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 15, 2007 4:31 am 
Newbie

Joined: Wed Jan 10, 2007 9:28 am
Posts: 6
this solution is for hibernate objects.

What is the solution in the case of importing an xml file. There is no objects, I can't use methods add.

(I say my pb again : during the import of xml file, hibernate don't set the father ID in the child ---> contraint integrity violated in the DB. What's the solution to od it automatically ? )


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