-->
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.  [ 8 posts ] 
Author Message
 Post subject: Modifying a Many to many
PostPosted: Wed Sep 14, 2005 8:04 pm 
Senior
Senior

Joined: Sat Sep 10, 2005 3:46 pm
Posts: 178
I have a form that allows users to add to and remove items from a many to many collection of a persistent class.

The form allows users to add and remove mutilple items at a time. After the user submits the form, the easiest thing for me to do is just clear out the collection and then add back in the items that are selected as opposed to trying to figure out which ones the user removed and which ones they added. I see that NHibernate is smart though and its sees what I am doing with the collection, so when it goes to update the database, it issues a delete to clear out the collection for the class and then it issues an insert for the items that were added to the collection.

So Im wondering if there is a good solution so that Im not deleting items from the db and just adding them right back in.


Last edited by jnapier on Thu Sep 15, 2005 2:50 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 2:49 am 
Senior
Senior

Joined: Sat Sep 10, 2005 3:46 pm
Posts: 178
Nevermind. I guess Nhibernate is not as smart as I thought it was. It appears that whenever the collection is modified in any way it will delete all of the items from the database and add all current items of the collection back into the table.

That seems a liitle inefficient, but I guess any other way would be very difficult.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 4:30 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
This may help you: http://www.hibernate.org/116.html#A13


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 2:54 pm 
Senior
Senior

Joined: Sat Sep 10, 2005 3:46 pm
Posts: 178
Thanks for the link, this says that I should not set the collection to a new collection in my setter. Of course not, I gernerally wouldn't allow the backing store of my collection to be changed. This particular class only has a getter for the collection. To modify the elements of the collection, the add, remove, clear operations must be used.

So you cant do this:
Code:
myClass.ItemList = new ArrayList();


You can only do this:
Code:
myClass.ItemList.Add(newItem);


So if the statement in the link you provided me should apply to NHibernate as well, then something is not working correctly. Can someone else verify that the behavior I am seeing is actually what is happening?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 3:46 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
It also depends on the kind of collection you use. Bags are usually the worst, because there is no way to identify the individual item of a bag to update it, so the only way to update the collection is to recreate it. And there are some other cases as well. Can you post your mappings?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 16, 2005 5:25 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
sergey wrote:
Bags are usually the worst, because there is no way to identify the individual item of a bag to update it, so the only way to update the collection is to recreate it.


So then what is best? An Iesi collection?? Because i'm using bags for everything at the moment..


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 16, 2005 12:06 pm 
Senior
Senior

Joined: Sat Sep 10, 2005 3:46 pm
Posts: 178
I am using a bag. I also would like to know what is best to use for a collection. Its a little hard to determine which is best to use : bag, set, list, or map.

Here are my mappings - probably doesn't mean much now though since you have mentioned that a bag will have the behavior I am seeing/

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="RemoteNet.Northrop.IbisWork.Domain.Model"
   assembly="RemoteNet.Northrop.IbisWork.Domain" >
   <class name="JobDescriptor" table="JobDescriptor">      
      <!--ID-->
      <id name="Id" column="JobDescriptorId" unsaved-value="0" access="nosetter.camelcase-underscore">
         <generator class="identity" />
      </id>
      
      <!--VERSION-->
      <version name="Version" column="Version" access="field.camelcase-underscore" ></version>
      
      <!--PROPERTIES-->
      <property name="Characteristics" column="Characteristics" length="500" access="nosetter.camelcase-underscore"/>
      <property name="Status" column="Status" not-null="true" access="field.camelcase-underscore" />
   
      <!--COLLECTIONS -->
      <bag name="Functions" table="JobDescriptorFunction" access="field.camelcase-underscore" lazy="true">
         <key column="JobDescriptorId" />
         <many-to-many class="Function"  column="TitleId" />
      </bag>            
   </class>
</hibernate-mapping>

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="RemoteNet.Northrop.IbisWork.Domain.Model"
   assembly="RemoteNet.Northrop.IbisWork.Domain" >
   <class name="Title" table="Title" mutable="false">
      <!--CACHE -->
      <cache usage="read-only" />
      
      <!--IDENTIFIER -->
      <id name="Id" type="System.Int32" column="TitleId" unsaved-value="0" access="nosetter.camelcase-underscore">
         <generator class="identity" />
      </id>
      
      <!--DISCRIMINATOR -->
      <discriminator column="Type" not-null="true" />
      
      <!--PROPERTIES-->
      <property name="Name" column="Name" length="75" not-null="true" access="field.camelcase-underscore" unique="true"/>
      <property name="Characteristics" column="Characteristics" length="1000" not-null="true" access="field.camelcase-underscore" />
      <property name="Status" column="Status" not-null="true" access="field.camelcase-underscore" />
   
      <!--SUB CLASSES-->
      <subclass name="Function" discriminator-value="1" >
      
      </subclass>
   
      <subclass name="Designation" discriminator-value="2" >
         <property name="JobCode" column="JobCode" length="6" access="field.camelcase-underscore" />
      </subclass>
   </class>

</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 16, 2005 1:30 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Sets are probably the best collection in this respect. Another one you can try is idbag, but it can't be used for many-to-many or one-to-many, and you need a separate ID column in the collection table.


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