-->
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.  [ 3 posts ] 
Author Message
 Post subject: Deleting nested collections with cascade all-delete-orphan
PostPosted: Tue Apr 24, 2007 5:27 pm 
Beginner
Beginner

Joined: Tue Sep 14, 2004 1:03 pm
Posts: 33
Location: Calgary, Alberta Canada
I'm having trouble with deleting an instance of an object that has a collection of object with nested collection of objects.
I have set the cascase on all the classes to all-delete-orphan.
NHibernate is able to delete the main object and all the objects in the first level collection. However when I add the link in the collection of objects I get the good old:
NHibernate.HibernateException: You may not dereference an collection with cascade="all-delete-orphan"

If I comment out the mapping from the Factor to the Criteria everything works as expected. But when its linked, it does not work.

Guidelines have a list of Factors.
Factors have a list of Criterion.

When I don't map the List of Criterion in Factors, everything deletes just fine.

When I map the list of criterion in Factors, I get the dereference error. It seems that NHibernate chokes on the collection that has collections. The list of Criterion is implemented the same way the List of factors is implemented in the Guideline.


Hibernate version: 1.2.0 CR2

Mapping documents:
<class name="AMEC.EE.Sage.Domain.Entities.Gs.Guideline, Sage.Domain.Entities.Gs"
table="GS.GUIDELINES"
lazy="true">
<id name="id"
column="GUIDELINE_ID"
type="System.Int64"
access="field"
unsaved-value="0">
<generator class="identity" />
</id>
<property name="Author"
column="AUTHOR"
type="System.String"
not-null="true"
length="50"
unique="false" />
<property name="Date"
column="DATE"
type="System.DateTime"
not-null="true"
unique="false" />
<property name="IsRegulated"
column="IS_REGULATED"
type="System.Boolean"
not-null="true"
unique="false" />
<property name="Title"
column="TITLE"
type="System.String"
not-null="true"
length="200"
unique="false" />
<property name="RowGuid"
column="ROWGUID"
type="System.Guid"
not-null="true"
unique="true" />
<many-to-one name="Organization"
column="ORGANIZATION_ID"
not-null="false"
class="AMEC.EE.Sage.Domain.Entities.Core.Organization, Sage.Domain.Entities.Core"
unique="false"
cascade="none"
outer-join="true" />
<bag name="factors"
access="field"
table="FACTORS"
schema="GS"
inverse="true"
generic="true"
cascade="all-delete-orphan">
<key column="GUIDELINE_ID" />
<one-to-many class="AMEC.EE.Sage.Domain.Entities.Gs.Factor, Sage.Domain.Entities.Gs"/>
</bag>
<bag name="regions"
inverse="false"
cascade="none"
lazy="false"
access="field"
table="GUIDELINES_REGIONS"
schema="GS">
<key column="GUIDELINE_ID"/>
<many-to-many class="AMEC.EE.Sage.Domain.Entities.Core.Region, Sage.Domain.Entities.Core"
column="REGION_ID" />
</bag>
</class>

<class name="AMEC.EE.Sage.Domain.Entities.Gs.Factor, Sage.Domain.Entities.Gs"
table="GS.FACTORS"
lazy="true" >
<id name="id"
column="FACTOR_ID"
type="System.Int64"
unsaved-value="0"
access="field">
<generator class="identity"/>
</id>
<!--<version name="Version"
column="VERSION"
type="System.Int64"
unsaved-value="0"/>-->
<!--<timestamp name="TimeStamp"
column="VERSION" />-->
<property name="TimeStamp"
column="VERSION"
type="System.Byte[]"
not-null="true"
insert="false"
update="false"
unique="true"/>
<property name="Name"
column="NAME"
type="System.String"
length="100"
not-null="true"
unique="false" />
<property name="Description"
column="DESCRIPTION"
type="System.String"
length="1000"
not-null="false"
unique="false" />
<property name="Value"
column="VALUE"
type="System.String"
length="150"
not-null="true"
unique="false" />
<property name="RowGuid"
column="ROWGUID"
type="System.Guid"
not-null="false"
unique="true"
access="property"/>
<many-to-one name="Type"
column="TYPE_ID"
class="AMEC.EE.Sage.Domain.Entities.Gs.FactorType, Sage.Domain.Entities.Gs"
cascade="none" />
<many-to-one name="Guideline"
column="GUIDELINE_ID"
class="AMEC.EE.Sage.Domain.Entities.Gs.Guideline, Sage.Domain.Entities.Gs"
not-null="true"
unique="false"
outer-join="false"
cascade="none" />
<many-to-one name="Unit"
column="UNIT_ID"
class="AMEC.EE.Sage.Domain.Entities.Core.Unit, Sage.Domain.Entities.Core"
not-null="false"
unique="false"
outer-join="false"
cascade="none" />
<many-to-one name="parent"
column="PARENT"
class="AMEC.EE.Sage.Domain.Entities.Gs.Factor, Sage.Domain.Entities.Gs"
not-null="false"
cascade="none"
access="field"/>
<bag name="factors"
access="field"
table="FACTORS"
schema="GS"
inverse="true"
generic="true"
cascade="all-delete-orphan">
<key column="PARENT" />
<one-to-many class="AMEC.EE.Sage.Domain.Entities.Gs.Factor, Sage.Domain.Entities.Gs"/>
</bag>
<bag name="criteria"
access="field"
table="CRITERIA"
schema="GS"
inverse="true"
generic="true"
cascade="all-delete-orphan">
<key column="FACTOR_ID" />
<one-to-many class="AMEC.EE.Sage.Domain.Entities.Gs.Criterion, Sage.Domain.Entities.Gs"/>
</bag>
</class>

<class name="AMEC.EE.Sage.Domain.Entities.Gs.FactorType, Sage.Domain.Entities.Gs"
schema="GS"
table="FACTOR_TYPES"
lazy="true" >
<id name="id"
column="TYPE_ID"
type="System.String"
access="field"
length="5">
<generator class="assigned" />
</id>
<property name="Name"
column="NAME"
type="System.String"
length="35"
not-null="true"
unique="true" />
<property name="Description"
column="DESCRIPTION"
type="System.String"
length="250"
not-null="false"
unique="false" />
</class>

<class name="AMEC.EE.Sage.Domain.Entities.Gs.Criterion, Sage.Domain.Entities.Gs"
table="GS.CRITERIA"
lazy="true">
<id name="id"
column="CRITERIA_ID"
type="System.Int64"
access="field"
unsaved-value="0">
<generator class="identity" />
</id>
<property name="TimeStamp"
column="VERSION"
type="System.Byte[]"
not-null="true"
insert="false"
update="false"
unique="true"/>
<property name="Value"
column="VALUE"
type="System.Decimal"
not-null="false"
unique ="false"/>
<property name="Lookup"
column="LOOKUP_XML_STRING"
type="System.String"
not-null="false"
unique="false" />
<many-to-one name="Type"
column="TYPE_ID"
cascade="none"
class="AMEC.EE.Sage.Domain.Entities.Gs.CriterionType, Sage.Domain.Entities.Gs" />
<many-to-one name="Analyte"
column="ANALYTE_ID"
cascade="none"
class="AMEC.EE.Sage.Domain.Entities.Adm.Analyte, Sage.Domain.Entities.Adm" />
<property name="RowGuid"
column="ROWGUID"
type="System.Guid"
not-null="false"
unique="true" />
<many-to-one name="Factor"
column="FACTOR_ID"
class="AMEC.EE.Sage.Domain.Entities.Gs.Factor, Sage.Domain.Entities.Gs"
not-null="true"
unique="false"
outer-join="false"
cascade="none"/>
<many-to-one name="Unit"
column="UNIT_ID"
class="AMEC.EE.Sage.Domain.Entities.Core.Unit, Sage.Domain.Entities.Core"
not-null="false"
unique="false"
outer-join="false"
cascade="none" />
</class>

<class name="AMEC.EE.Sage.Domain.Entities.Gs.CriterionType, Sage.Domain.Entities.Gs"
table="GS.CRITERIA_TYPES"
lazy="true">
<id name="id"
column="TYPE_ID"
type="System.String"
access="field"
length="5">
<generator class="assigned" />
</id>
<property name="Name"
column="NAME"
type="System.String"
length="35"
not-null="true"
unique="true" />
<property name="Description"
column="DESCRIPTION"
type="System.String"
length="250"
not-null="false"
unique="false" />
<!-- TODO: need to map XML_SCHEMA -->
</class>

Code between sessionFactory.openSession() and session.close():
BeginTransaction();
Session.Delete(guideline);
Commit();


Full stack trace of any exception that occurs:
NHibernate.HibernateException: You may not dereference an collection with cascade="all-delete-orphan"

at NHibernate.Impl.SessionImpl.ProcessDereferencedCollection(IPersistentCollection coll)
at NHibernate.Impl.SessionImpl.UpdateUnreachableCollection(IPersistentCollection coll)
at NHibernate.Impl.SessionImpl.FlushCollections()
at NHibernate.Impl.SessionImpl.FlushEverything()
at NHibernate.Impl.SessionImpl.Flush()
at NHibernate.Transaction.AdoTransaction.Commit()
at AMEC.EE.Sage.Domain.Persistence.Nhbr.NHibernateDaoBase.Commit() in NHibernateDaoBase.cs:line 80
at AMEC.EE.Sage.Domain.Persistence.Nhbr.NHibernateDao`2.Delete(TObject obj) in NHibernateDao.cs:line 224
at AMEC.EE.Sage.Domain.Persistence.Nhbr.NHibernateDaoRowGuid`2.Delete(Guid rowguid, TObject& obj) in NHibernateDaoRowGuid.cs:line 55
at AMEC.EE.Sage.Domain.Persistence.Nhbr.NHibernateDaoRowGuid`2.Delete(Guid rowguid) in NHibernateDaoRowGuid.cs:line 39
at AMEC.EE.Sage.Tests.Domain.Persistence.Gs.Nhbr.TestGuidelineDao.TestDeleteGuidelineByGuid() in TestGuidelineDao.cs:line 113

Name and version of the database you are using:
SQL Server 2005


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 17, 2008 6:24 pm 
Beginner
Beginner

Joined: Wed Jul 05, 2006 12:45 pm
Posts: 21
Did you ever find a solution to this issue?

Thanks very much,

-Sasha Borodin


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 12:52 pm 
Beginner
Beginner

Joined: Tue Sep 14, 2004 1:03 pm
Posts: 33
Location: Calgary, Alberta Canada
I don't think so. I'm looking at my code and the mappings look fairly much the same as what I've posted before. I also notice that I've commented out my unit tests where I test adding add deleting. Likely because I've gone through a bit a design change.

In some other projects, I manage deleting objects myself. Either through setting the cascades on the database itself. Or, before deleting the parent, I go through and delete the children first. If this is the case, the mapping needs to be changed so that I'm persisting additions only.

Change Cascade to save-update or none, if none you would have to completely manage the collections yourself.

Code:
BeginTransaction();
if(guideline.Factors != null){
    foreach(Factor f in guideline.Factors){
        if(f.Criteria != null){
            foreach(Criterion c in f.Criteria){
                Session.Delete(c);
            }
        Session.Delete(f);
    }
}
Session.Delete(guideline);


If the database has cascade deletes enabled, all you should have to do is delete the parent and the database will purge the rest.

I'm hoping to readdress this in the next few weeks.

Darin


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.