-->
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: Many-to-many Delete /w cascading...
PostPosted: Tue Oct 02, 2007 7:48 pm 
Newbie

Joined: Wed Jun 15, 2005 12:22 pm
Posts: 7
Hello all. I've been working with nhibernate for a few months now and I feel like I've never been able to fully grasp many-to-many relationships (including cascading). As a last ditch effort, I come to you with mapping files in hand. :) I have a many-to-many relationship in my database that includes three tables (Field, FieldGroup, and Group). FieldGroup represents a cross-table between the remaining two tables. Here are the relevant portions of my mapping files.

Field
<set name="FieldGroups" access="nosetter.camelcase" cascade="all">
<key column="FieldID" />
<one-to-many class="FieldGroup"/>
</set>

FieldGroup
<many-to-one name="Group" class="TraceGroup">
<column name="GroupID" />
</many-to-one>
<many-to-one name="Field" class="Field">
<column name="FieldID" />
</many-to-one>

Group
<set name="FieldGroups" inverse="true" lazy="true" access="nosetter.camelcase" cascade="none">
<key column="GroupID"/>
<one-to-many class="FieldGroup"/>
</set>

I can save FieldGroup records just fine, however, when I attempt to delete I get the following error: Cannot insert the value NULL into column 'FieldID', table FieldGroup';

I read in a blog post that I could possibly put inverse="true" on the collection inside the Field mapping, however, that isn't a good solution because I want the Field mapping to handle the groups and not the other way around. Has anyone fought this battle before and is it possible to simply clear the collection of FieldGroups on my Field object and persist it, therefore, deleting the relevant records in the FieldGroup table?

Any assistance is greatly appreciated. Unless I can find an answer to this question I'll have to write what I consider to be poor, one-off code chunks to handle removing and persisting child objects (FieldGroups) as opposed to having the mapping handle it for me via cascades. Surely this isn't the solution most people are using now...is it?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 02, 2007 9:25 pm 
Hibernate Team
Hibernate Team

Joined: Tue Jun 13, 2006 11:29 pm
Posts: 315
Location: Calgary, Alberta, Canada
I am not sure if this would solve your problem. Nonetheless, here is an alternative that I have used with success:
Code:
<class name="Field" table="...">
    ...
    <set name="FieldGroups">
        <key column="FieldID"/>
        <composite-element class="FieldGroup">
            <many-to-one name="Group" column="GroupID"/>
        </composite-element>
    </set>
</class>

Note that there is no need to specify cascade on the <set> since it is owned by Field and a FieldGroup does not really have its own lifecycle. However, you do need to override FieldGroup.Equals() and GetHashCode() for this to function properly.

I believe your mapping in Group would remain the same if you use the above approach.

Edit: Nevermind. Actually, <one-to-many class="FieldGroup"/> would not work because "FieldGroup" is not an entity. So the above would only work if you can live with a unidirectional relationship from Field to FieldGroup to Group

_________________
Karl Chu


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 03, 2007 12:47 pm 
Newbie

Joined: Wed Jun 15, 2005 12:22 pm
Posts: 7
Karl. I appreciate your response, however, lets try a fresh start. I've given up on cascading now and I simply want to get the records in the many-to-many relation to save.

Can anybody tell me why I'm still receiving the following error:

Cannot insert the value NULL into column 'FieldCropID', table FieldCHTraceGroup';

Here are my latest mappings (including naming changes)
Mapping: FieldCropHistory.hbm.xml
<set name="FieldCHTraceGroups" access="nosetter.camelcase" cascade="none">
<key column="FieldCropID" />
<one-to-many class="FieldCHTraceGroup"/>
</set>

Mapping: FieldCHTraceGroup
<many-to-one name="TraceGroup" class="TraceGroup">
<column name="TraceID" />
</many-to-one>
<many-to-one name="FieldCropHistory" class="FieldCropHistory">
<column name="FieldCropID" />
</many-to-one>

Mapping: TraceGroup
<set name="FieldCHTraceGroups" inverse="true" lazy="true" access="nosetter.camelcase" cascade="none">
<key column="TraceID"/>
<one-to-many class="FieldCHTraceGroup"/>
</set>


Here's the c# I'm using to try and save a FieldCHTraceGroup record without any cascading:

// fieldCropHistory and traceGroup are freshly pulled
// inside the constructor for fchTraceGroup the traceGroup and // fieldCropHistory properties are set on the object
FieldCHTraceGroup fchTraceGroup = new FieldCHTraceGroup(DateTime.Now, DateTime.Now, traceGroup, fieldCropHistory);
fieldCropHistory.FieldCHTraceGroups.Add(fchTraceGroup);

Looking at most of the examples I've found I'm doing this perfectly right yet I still receive the above error message.

Any help is appreciated.

Corey


Top
 Profile  
 
 Post subject: Re: Many-to-many Delete /w cascading...
PostPosted: Thu Oct 04, 2007 12:17 am 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
shock56 wrote:
I read in a blog post that I could possibly put inverse="true" on the collection inside the Field mapping, however, that isn't a good solution because I want the Field mapping to handle the groups and not the other way around.


I think you are confused about the purpose of the inverse attribute. All it determines is which mapping takes responsibility for setting the foreign key on the child object. From the object side, you can "handle" things from whichever side you like. You can also use cascades, which also encforce a type of "handling" direction. The error you are getting will be cleared up in a jiffy by just setting the set to inverse="true", and I don't think it will have the deleterious effects you imagine.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 04, 2007 1:32 am 
Newbie

Joined: Wed Jun 15, 2005 12:22 pm
Posts: 7
marcal,

Thank you for your response. I think you are correct. I seem to be struggling with what others deem a relatively easy concept.

I'm going to post an example application on my blog at the following location: http://www.coreyperkins.com/?page_id=13 (please excuse the name of the file, I was a bit frustrated this evening). If anyone can look at this feel free to download it and tell me where I'm going wrong. Inside the 'res' directory there is a sql script that can be used to generate the database my mapping files are written against. Also, I included the version of nhibernate I'm currently referencing in the 'lib' directory.

Back to the inverse attribute. I was under the impression that because I had inverse="true" on the collection in the tracegroup mapping I did not need it on the collection in the fieldcrophistory mapping. I feel like after today I have a better grasp but I'm still not getting the results I desire. Even after placing the inverse="true" attribute on the collection in both the fieldcrophistory and the tracegroup mappings. As usual thanks for the help s far and thanks ahead.

Corey


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 04, 2007 10:09 am 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
What are the results you desire?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 04, 2007 11:31 am 
Newbie

Joined: Wed Jun 15, 2005 12:22 pm
Posts: 7
I would like to be able to save the records in the cross table without requiring any type of cascading on the many-to-many relationship and I would very much like to figure out why I am getting the exception in the current implementation. My apologies for not being very clear...this bug has be losing sleep. :)

P.S. I posted a bad version of the sample application and I'll post a new one shortly. Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 04, 2007 3:01 pm 
Newbie

Joined: Wed Jun 15, 2005 12:22 pm
Posts: 7
Thanks for the feedback guys, I've located my problem. It was caused because a parent collection outside of the mappings I've been displaying in this post required inverse=true to be set. nHibernate has a bit of a learn curve and is far from perfect, but it'll get the job done and I'm learning. :)


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.