-->
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.  [ 6 posts ] 
Author Message
 Post subject: cascading deletes with multiple sets of children
PostPosted: Tue Nov 22, 2005 12:44 pm 
Newbie

Joined: Tue Nov 22, 2005 12:16 pm
Posts: 3
Hibernate version: 3.0.5

We have an object model that has a parent object that has multiple child object sets. Each child object type is modeled as a one-to-many (1-0..*) set with all-delete-orphan cascading. The specific mapping file is shown below. Customer is the parent object and it has Domain, UserGroup, and BranchGroup children.

I'm attempting a delete of Customer and want it to cascade to all children.

UserGroup and BranchGroup also have a many-to-one (0..*-1) association to Domain (also shown below). As such, BranchGroups and UserGroups must be deleted before Domains when a Customer is deleted. If Domain is deleted before BranchGroups a PropertyValueException occurs (shown below) indicating a not-null property violation occured deleting BranchGroup. It appears the order that child types are cascaded (including deletion) from a parent is a function of their ordering in the parent mapping file.

Any suggestion, short of changing the mapping file ordering, how to get around this problem?

Would an event listener (or interceptor) allow me to change the ordering programatically or is there a better way?

Thanks,

Code:
<hibernate-mapping default-cascade="save-update">
    <class name="com.bluenotenetworks.common.management.sm.CustomerImpl"  dynamic-insert="false" dynamic-update="false" table="CUSTOMER">
        <id name="id" type="java.lang.Long" unsaved-value="null">
            <column name="ID" sql-type="BIGINT"/>
            <generator class="native">
            </generator>
        </id>

        <property name="name" type="java.lang.String">
            <column name="NAME" not-null="true" unique="true" sql-type="CHARACTER VARYING(1024)" index="customer_name"/>
        </property>
        <many-to-one name="network" class="com.bluenotenetworks.common.management.sm.NetworkImpl"  fetch="select" cascade="none" foreign-key="CUSTOMER_NETWORK_FKC">
            <column name="NETWORK_FK" not-null="true" sql-type="BIGINT"/>
        </many-to-one>
        <set name="domains" order-by="CUSTOMER_FK" lazy="true" fetch="select" inverse="true" cascade="all-delete-orphan">
            <key foreign-key="DOMAIN_CUSTOMER_FKC">
                <column name="CUSTOMER_FK" sql-type="BIGINT"/>
            </key>
            <one-to-many class="com.bluenotenetworks.common.management.sm.DomainImpl"/>
        </set>
        <set name="branchGroups" order-by="CUSTOMER_FK" lazy="true" fetch="select" inverse="true" cascade="all-delete-orphan">
            <key foreign-key="BRANCH_GROUP_CUSTOMER_FKC">
                <column name="CUSTOMER_FK" sql-type="BIGINT"/>
            </key>
            <one-to-many class="com.bluenotenetworks.common.management.sm.BranchGroupImpl"/>
        </set>
        <set name="userGroups" order-by="CUSTOMER_FK" lazy="true" fetch="select" inverse="true" cascade="all-delete-orphan">
            <key foreign-key="USER_GROUP_CUSTOMER_FKC">
                <column name="CUSTOMER_FK" sql-type="BIGINT"/>
            </key>
            <one-to-many class="com.bluenotenetworks.common.management.sm.UserGroupImpl"/>
        </set>
    </class>
</hibernate-mapping>


Code:
<hibernate-mapping default-cascade="save-update">
    <class name="com.bluenotenetworks.common.management.sm.BranchGroupImpl"  dynamic-insert="false" dynamic-update="false" table="BRANCH_GROUP">
        <id name="id" type="java.lang.Long" unsaved-value="null">
            <column name="ID" sql-type="BIGINT"/>
            <generator class="native">
            </generator>
        </id>

        <property name="name" type="java.lang.String">
            <column name="NAME" not-null="true" unique="false" sql-type="CHARACTER VARYING(1024)" index="branch_group_name"/>
        </property>
        <many-to-one name="customer" class="com.bluenotenetworks.common.management.sm.CustomerImpl"  fetch="select" cascade="none" foreign-key="BRANCH_GROUP_CUSTOMER_FKC">
            <column name="CUSTOMER_FK" not-null="true" sql-type="BIGINT"/>
        </many-to-one>
        <many-to-one name="domain" class="com.bluenotenetworks.common.management.sm.DomainImpl"  fetch="select" cascade="none" foreign-key="BRANCH_GROUP_DOMAIN_FKC">
            <column name="DOMAIN_FK" not-null="true" sql-type="BIGINT"/>
        </many-to-one>
    </class>
</hibernate-mapping>


Code:
<hibernate-mapping default-cascade="save-update">
    <class name="com.bluenotenetworks.common.management.sm.UserGroupImpl"  dynamic-insert="false" dynamic-update="false" table="USER_GROUP">
        <id name="id" type="java.lang.Long" unsaved-value="null">
            <column name="ID" sql-type="BIGINT"/>
            <generator class="native">
            </generator>
        </id>

        <property name="name" type="java.lang.String">
            <column name="NAME" not-null="true" unique="false" sql-type="CHARACTER VARYING(1024)" index="user_group_name"/>
        </property>
        <many-to-one name="customer" class="com.bluenotenetworks.common.management.sm.CustomerImpl"  fetch="select" cascade="none" foreign-key="USER_GROUP_CUSTOMER_FKC">
            <column name="CUSTOMER_FK" not-null="true" sql-type="BIGINT"/>
        </many-to-one>
        <many-to-one name="domain" class="com.bluenotenetworks.common.management.sm.DomainImpl"  fetch="select" cascade="none" foreign-key="USER_GROUP_DOMAIN_FKC">
            <column name="DOMAIN_FK" not-null="true" sql-type="BIGINT"/>
        </many-to-one>
    </class>
</hibernate-mapping>


Code:
org.springframework.orm.hibernate3.HibernateSystemException: not-null property references a null or transient value: com.bluenotenetworks.common.management.sm.BranchGroupImpl.domain; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: com.bluenotenetworks.common.management.sm.BranchGroupImpl.domain
org.hibernate.PropertyValueException: not-null property references a null or transient value: com.bluenotenetworks.common.management.sm.BranchGroupImpl.domain
   at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
   at org.hibernate.event.def.DefaultDeleteEventListener.deleteEntity(DefaultDeleteEventListener.java:205)
   at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:109)
   at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:587)
   at org.hibernate.engine.Cascades$1.cascade(Cascades.java:68)
   at org.hibernate.engine.Cascades.cascadeAssociation(Cascades.java:771)
   at org.hibernate.engine.Cascades.cascade(Cascades.java:720)
   at org.hibernate.engine.Cascades.cascadeCollection(Cascades.java:895)
   at org.hibernate.engine.Cascades.cascadeAssociation(Cascades.java:792)
   at org.hibernate.engine.Cascades.cascade(Cascades.java:720)
   at org.hibernate.engine.Cascades.cascade(Cascades.java:847)
   at org.hibernate.engine.Cascades.cascade(Cascades.java:819)
   at org.hibernate.event.def.DefaultDeleteEventListener.cascadeBeforeDelete(DefaultDeleteEventListener.java:248)
   at org.hibernate.event.def.DefaultDeleteEventListener.deleteEntity(DefaultDeleteEventListener.java:201)
   at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:109)
   at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:579)
   at org.springframework.orm.hibernate3.HibernateTemplate$25.doInHibernate(HibernateTemplate.java:692)
   at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:312)
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:686)
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:682)
   at com.bluenotenetworks.sm.services.config.ConfigManagerImpl.delete(ConfigManagerImpl.java:229)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:288)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:155)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:122)
   at org.springframework.orm.hibernate3.HibernateInterceptor.invoke(HibernateInterceptor.java:163)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:57)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
   at $Proxy1.delete(Unknown Source)
   at com.bluenotenetworks.sm.services.test.TestBranchManager.testCreateDeleteBranchGroups(TestBranchManager.java:55)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:31)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 23, 2005 4:00 am 
Expert
Expert

Joined: Mon Jul 04, 2005 5:19 pm
Posts: 720
Code:
org.hibernate.PropertyValueException: not-null property references a null or transient value: com.bluenotenetworks.common.management.sm.BranchGroupImpl.domain


the object of the domain property is either null or transient. take a look at the documentation on the differences between 'transient', 'persistent' and 'detached' state. as long as this happens, you cannot bring the branch into persitent state (do something w/ it in Hibernate).


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 23, 2005 9:33 am 
Newbie

Joined: Tue Nov 22, 2005 12:16 pm
Posts: 3
Thanks Dennis. However, this error is occuring during a cascading delete of an already persisted object graph, rooted at Customer. I believe the problem has to do with the fact that the Domains under Customer are being deleted first and there is a required association from BranchGroups and UserGroups to Domains.

During a cascading delete, I'd like to have the Domains deleted last.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 07, 2005 12:11 pm 
Newbie

Joined: Mon Sep 13, 2004 9:44 am
Posts: 13
I have the exact same problem, except that I'm using annotations instead of an XML mapping file. I found that I could influence the order of the cascade operations by changing the order of the getter method declarations in my annotated class.

Did you find a better way? It may be better to do the 'cascade' manually in the code rather than relying on the mapping order.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 07, 2005 12:19 pm 
Newbie

Joined: Tue Nov 22, 2005 12:16 pm
Posts: 3
I ended up modeling the child to child associations as optional (I.e. instead of a many-to-one ([0..*]-[1]) I changed it to [0..*]-[0..1]). This allowed the cascading to work regardless of the order. I enforce the mutliplicity of the association end that was supposed to be [1] in the code during creation.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 07, 2005 1:24 pm 
Newbie

Joined: Mon Sep 13, 2004 9:44 am
Posts: 13
Yes, another sensible compromise.

It would be nice to be able to specify a cascade ordering in the mappings, but I guess that in general the problem is not soluble as the object graph may be too complex.


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