-->
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.  [ 12 posts ] 
Author Message
 Post subject: Cascade Delete problem using a unidirectional asscoiation
PostPosted: Thu Nov 09, 2006 4:57 am 
Newbie

Joined: Fri Feb 24, 2006 3:09 am
Posts: 6
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: 3.0

Mapping documents:
<class name="Child">
<id name="id" column="childId">
</id>
<many-to-one name="parent" cascade="all"
column="parentId"
not-null="true"/>
/class>
<class name="parent">
<id name="id" column="parentId">
</id>
/class>

Code between sessionFactory.openSession() and session.close():

Session session = TestEntity.currentSession();
//STORE
Transaction tx = session.beginTransaction();
Parent parent = new Parent();
parent.setParentId("101");
session.delete(parent);
tx.commit();
sesson.close();

Full stack trace of any exception that occurs:
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not delete: [*****.Parent#101]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
******.....
Caused by: java.sql.SQLException: Cannot delete or update a parent row: a foreign key constraint fails

Name and version of the database you are using:
mysql 4.1.11
The generated SQL (show_sql=true):
dont have them
Debug level Hibernate log excerpt:
dont have them

Problems with Session and transaction handling?
HI,
This is Poonam.
The problem here is when I try to delete the Parent it gives exception of foreign key constraint failed.
My expectation was delete of a Parent should also delete the Child as I have used cascade="all" in Child.
Can some one tell me how to achieve a cascade delete using seprate relations for Parent and Child.
Note: I do not want to use the approach of declaring the child as a collection inside the parent as it becomes a heavy operation when I do getParent() all children and then all successors of each child are retrieved. This becomes an expensive operation.
Can someone please help me using a cascade delete without using collections.
Thanks in advance
-Poonam.




Read this: http://hibernate.org/42.html


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 09, 2006 6:16 am 
Beginner
Beginner

Joined: Mon Nov 06, 2006 2:40 am
Posts: 29
Location: New Delhi, India
In this case you have to define cascade delete at your database level.
"ON DELETE CASCADE "


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 6:35 am 
Newbie

Joined: Fri Feb 24, 2006 3:09 am
Posts: 6
Thanks in advance Sagi...
but that can be done even without using Hibernate using DDL statements.
My question is how do I define such a relationship in the Hibernate mapping file.
Has nobody come across this problem as of now..or can someone provide me links to applications that have successfully defined such a relationship.
-Poonam.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 7:28 am 
Beginner
Beginner

Joined: Mon Nov 06, 2006 2:40 am
Posts: 29
Location: New Delhi, India
you need to define one-to-many relation in Parent class also,
here cascade is "delete-orphan" means, delete the child if parent does not exist, lasy is set to true so that it does not become expensive operation.

Code:
<set inverse="true" name="childern" lazy="true" cascade="delete-orphan"  >
<key column="id" />
<one-to-many class="Child" not-found="ignore" />
</set>


Regards,

Rohit (Sagi)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 8:22 am 
Newbie

Joined: Fri Feb 24, 2006 3:09 am
Posts: 6
Sorry Rohit that does not solve my problem.
I had mentioned in my first post that I am looking at a solution which is without using collections.
Using <set> with lazy='true' makes it as good as not related,
coz the set of children will not be fetched when I fetch a parent.

Also, I had tried to set the max_fetch_depth=1 with lazy=false using collections so that only the first level of children i.e.the contained collections is fetched along with the parent.
But when I execute a GET, I see that the entire tree is fetched.
setting max_fetch_depth does not make a difference.
Am I wrong somewhere here. If yes, please correct me.
-Poonam


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 12:04 pm 
Regular
Regular

Joined: Tue Feb 24, 2004 11:42 am
Posts: 56
http://www.hibernate.org/hib_docs/v3/re ... -manytoone

"[b]Note that single valued associations (many-to-one and one-to-one associations) do not support orphan delete.[/b]
"

So it will not delete and cascade.

Well this does not answer your problem but atleast lets you know that you will have to change the mapping. if this hepls please do rate.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 10:52 pm 
Beginner
Beginner

Joined: Mon Nov 06, 2006 2:40 am
Posts: 29
Location: New Delhi, India
PoonamAgarwal wrote:
... that does not solve my problem.
I had mentioned in my first post that I am looking at a solution which is without using collections.


As per the documentation you cannot delete without relation, so its mendatory for you to define one-to-many relation in parent table

Regards,

Rohit(Sagi)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 13, 2006 11:07 pm 
Newbie

Joined: Wed Nov 01, 2006 10:12 pm
Posts: 4
we had the same problem we did it manually since we wanted a uni directional assosciation .....


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 9:50 am 
Newbie

Joined: Fri Feb 24, 2006 3:09 am
Posts: 6
Well, thanks for the suggestion subu......
if not without a collection then will a bidirectional one-to-may relationship work out.
I am just fighting with the following mapping:
<class name="xxx.ServerDetails"
lazy="false"
extends="xxx.Entity">
<key column="entityId" />
<property name="Name" column="Name" />

<set name="endPoints" table="SERVER_ENDPOINTS" lazy="false"
inverse="true"
cascade="all">
<cache usage="read-write"/>
<key column="entityId" />
<one-to-many
class="xxx.EndPointCapability"/>
</set>
</class>

<class name="xxx.EndPointCapability"
table="EndPointCapability" lazy="false">
<cache usage="read-write" />
<id name="endPointId" column="endPointId"></id>
<many-to-one name="serverDetails" column="serverDetails"
class="xxx.ServerDetails"
lazy="false" cascade="all" not-null="true"/>
<property name="ename" column="ename" />
</class>


Now I am using Spring HibernateTemplate,
Adding a Server autom automatically adds a EndPoint.
Code:
  HibernateTemplate ht = new HibernateTemplate(this.getSessionFactory());   
    ServerDetails serverDet = new ServerDetails();
    serverDet.setEntityId("en1");
    EndPointCapability  endPoint1 = new EndPointCapability(new Long(101),serverDet);
    serverDet.addEndPoint(endPoint1);
    ht.save(serverDet);


But, Delete of a Server does not automatically delete the EndPoint.
Code

Code:
HibernateTemplate ht = new HibernateTemplate(this.getSessionFactory());
    List serverList = ht.loadAll(ServerDetails.class);   
    ServerDetails serverDet = (ServerDetails )serverList.get(0);
    ht.delete(serverDet);


Quote:
throws Exception DataIntegrityViolationException

Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: Hibernate operation: could not delete: [xxx.ServerDetails#en1]; SQL [delete from ServerDetails where entityId=?]; Integrity constraint violation FKA6D55C8D4E0F4DE8 table: ENDPOINTCAPABILITY in statement [delete from ServerDetails where entityId=?]; nested exception is java.sql.SQLException: Integrity constraint violation FKA6D55C8D4E0F4DE8 table: ENDPOINTCAPABILITY in statement [delete from ServerDetails where entityId=?]
java.sql.SQLException: Integrity constraint violation FKA6D55C8D4E0F4DE8 table: ENDPOINTCAPABILITY in statement [delete from ServerDetails where entityId=?]
at org.hsqldb.jdbc.Util.throwError(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:101)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2296)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2442)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:73)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:394)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:367)
at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:788)

Now, I am not able to make out what the problem is .Can someone help.
How will the cascade delete work in case of a bidirectional one-to-many relationship.
-Poonam.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 12:04 pm 
Regular
Regular

Joined: Tue Feb 24, 2004 11:42 am
Posts: 56
u have to set cascade-all,delete-orphan


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 14, 2006 12:04 pm 
Regular
Regular

Joined: Tue Feb 24, 2004 11:42 am
Posts: 56
u have to set cascade-all,delete-orphan


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 15, 2006 7:58 am 
Newbie

Joined: Fri Feb 24, 2006 3:09 am
Posts: 6
Well I am done.....got the solution to my problem.
Some credit does go to Sagi for pointing me to use the attribute not-found="ignore"
which helps to get rid of the DataIntegrityViolationException.
The mapping file for a bi-directional one-to-many relationship is as follows:
Code:
<class name="xxx.ServerDetails" lazy="false">
   <key column="entityId" />
   <property name="Name" column="Name" />
   <set name="endPoints" table="SERVER_ENDPOINTS" lazy="false"
   cascade="all"
   <cache usage="read-write"/>
   <key column="entityId" />
   <one-to-many not-found="ignore"
         class="xxx.EndPointCapability"/>
    </set>   
</class>

<class name="xxx.EndPointCapability" table="EndPointCapability" lazy="false">
   <id name="endPointId" column="endPointId"></id>
   <many-to-one name="serverDetails" column="serverDetails"
          class="xxx.ServerDetails"
             lazy="false" cascade="all" not-null="true"/>
   <property name="ename" column="ename" />
</class>

Here : things tested are :
1. adding a parent( with attahced child) add the child automatically. TestCode:
Code:
HibernateTemplate ht = new HibernateTemplate(this.getSessionFactory());   
    ServerDetails serverDet = new ServerDetails();
    serverDet.setEntityId("en1");
    EndPointCapability  endPoint1 = new EndPointCapability(new Long(101),serverDet,
        "endPoint1",0);   
    serverDet.addEndPoint(endPoint1);
    ht.save(serverDet);


2. Delete a Parent deletes the child.(use cascade-"all" in the parent's set)
Code:
  //Delete the first Server
   HibernateTemplate ht = new HibernateTemplate(this.getSessionFactory());
    List serverList = ht.loadAll(ServerDetails.class);
    ServerDetails serverDet = (ServerDetails )serverList.get(0);
    System.out.println("TestOneToManyWithSpring.testDelServer()" + serverDet.getEndPoints().size()); //.iterator().next().setServerDetails(null);
    ht.delete(serverDet);


3. Delete a Child does not delete the parent( use not-found="ignore" in the parent's set)
Code:

   //Delete the first endpoint from Db
    HibernateTemplate ht = new HibernateTemplate(this.getSessionFactory());
    List epList = ht.loadAll(EndPointCapability.class);
    EndPointCapability ep  = (EndPointCapability )epList.get(0);
    System.out.println("testDelEP()" + ep.getServerDetails());
    ht.delete(ep);

I hope this link will be useful to those drenched in the cascade delete use-case.
Now, I am worried about my application performance. As a select of the root Object of my tree will fetch all contained objects. Well, dont want to discuss in the same topic.
Thanks to all those who attempted to help me.
-Poonam.


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