-->
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.  [ 4 posts ] 
Author Message
 Post subject: Delation on one side of a many-to-many relation
PostPosted: Fri Mar 17, 2006 4:28 am 
Newbie

Joined: Wed Mar 15, 2006 10:14 am
Posts: 7
Location: France
I'm working a little further of the example on the reference Hibernate documentation (Event and Person classes).
Here are the mapping files :
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
   <class name="events.Event" table="EVENTS">
      <cache usage="read-write" />
      <id name="id" column="EVENT_ID">
         <generator class="increment" />
      </id>
      <property name="date" type="timestamp" column="EVENT_DATE" />
      <property name="title" />
      <set name="participants" table="PERSON_EVENT" inverse="true">
         <key column="EVENT_ID" />
         <many-to-many column="PERSON_ID" class="events.Person" />
      </set>
   </class>
</hibernate-mapping>

and
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
   <class name="events.Person" table="PERSON" lazy="false">
      <cache usage="read-write" />
      <id name="id" column="PERSON_ID">
         <generator class="native" />
      </id>
      <property name="age" />
      <property name="firstname" length="80" />
      <property name="lastname" length="80" />
      <set name="events" table="PERSON_EVENT" lazy="true">
         <key column="PERSON_ID" />
         <many-to-many column="EVENT_ID" class="events.Event" />
      </set>
      <set name="emailAddresses" table="PERSON_EMAIL_ADDR" lazy="true"
         cascade="all">
         <key column="PERSON_ID" />
         <element type="string" column="EMAIL_ADDR" />
      </set>
   </class>
</hibernate-mapping>

Now, the issue : when I delete a Person having Events, Hibernate also deletes the rows in the PERSON_EVENT table (that's cool)
But when I delete and Event, I have a
Code:
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

How can I delete the Event ad its relations ?
Here is the code sample I use (the Event to delete comes from a previous transaction)
Code:
      Event event = (Event) request.getSession().getAttribute("event");
      Transaction tx = beginTransaction();
      getSession().delete(event);
      commitTransaction(tx);

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 17, 2006 4:48 am 
Newbie

Joined: Fri Feb 17, 2006 4:46 am
Posts: 10
I also experienced the same problem and after trying everything and asking everybody, I have come to the conclusion that there is indeed no simple solution. When you delete the entry at the inverse end of the association (i.e. the end that does not own the association), then Hibernate doesn't properly handle the case.

To circumvent this problem, you have two options:
1) model the association using an explicit object. In other words, don't use an implicit join table but use an explicit object for that. You'd have to change your relationship from Person*--*Event to Person 1--*PersonEvent*--1 Event (in the object model). Then make the associations cascade the delete to the explicit join object.
2) in your data access objects, make a method for this deletion case and manually navigate back to all persons of an event and remove the event from those persons. In addition to some programming effort, this has the drawback of resulting in a bunch of select statements slowing down your deletion process.

I think option 1 is usually preferable and if you really don't need any explicit attributes on the join object, you can try and hide it behind helper methods. Note that this means that you should only use many-to-many if you do not intend to delete on the inverse end...

Hope this helps.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 17, 2006 7:19 am 
Newbie

Joined: Wed Mar 15, 2006 10:14 am
Posts: 7
Location: France
What I tried, and doesn't work :
    Changing the cascading properties
    Using HQL (but the relation PERSON_EVENT is not visible in HQL)
    Using SQL (but delete is not usable)

And they dare say that the relation is bidirectional ...
In a short term view, I used the number 2 solution (navigate back and cut the relation from the source, even if slows down the application)


Top
 Profile  
 
 Post subject: Another solution ...
PostPosted: Fri Mar 17, 2006 7:32 am 
Newbie

Joined: Wed Mar 15, 2006 10:14 am
Posts: 7
Location: France
... is to skip the inverse="true"
Of course, it may lead to some data corruption ... so you've got to be very careful


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