-->
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: <composite-id> with embedded foreign key
PostPosted: Mon May 22, 2006 3:06 pm 
Regular
Regular

Joined: Mon May 22, 2006 2:30 pm
Posts: 74
I have run into an issue when deleting a collection of persistent objects, modeled as a "many-to-one" relationship, in which the "many" objects are mapped with a <composite-id> that contains a foreign key to the "one" object. When using the OO-like approach where you treat persistent objects as you would POJOs, it seems to result in two behaviours that are undesirable from a performance standpoint: 1) Each object in the collection must be loaded before it can be deleted, and 2) Each object in the collection is deleted with a separate SQL statement. This is very inefficient for large collections of objects. In this scenario, I do not want to delete the "one" object, only the "many" collection of objects.

I considered using HQL to perform the deletion, but that doesn't seem possible when the foreign key property is embedded in the <composite-id>. Normally, one could simply "delete from object2 where object2.fk_field = object1.id" and that would remove the entire "collection" of persistent objects. In this case, the foreign key property is not directly exposed because of the <composite-id> mapping.

Here is an example of this type of mapping:

<hibernate-mapping>
<class name="Class2" table="Class2_table" schema="APP">
<composite-id name="id" class="Class2Id">
<key-many-to-one name="class1" class="Class1>
<column name="class1_id" />
</key-many-to-one>
<key-property name="class2_sequential_number" type="integer">
<column name="class2_number" />
</key-property>
</composite-id>

The class1_id property is what you would like to use in HQL to delete all instances of class2 that are associated with class1, but I could find no examples that indicated if this was possible to reference in HQL, or what the syntax might be.

Has anyone run across this scenario, and come up with an approach using hibernate capabilities that allows all the objects in the collection to be removed with a single SQL statement?


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 22, 2006 3:25 pm 
Regular
Regular

Joined: Mon May 22, 2006 2:30 pm
Posts: 74
One of the other posts mentioned using a syntax like "object2.Id.class1_id", so it may be that I can use that in HQL to perform a bulk delete.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 22, 2006 11:54 pm 
Beginner
Beginner

Joined: Sat Jan 31, 2004 7:19 pm
Posts: 39
HQL works very similar to SQL.
Try:

Code:
Query q = session.createQuery("delete from Class2 where class1_id = ?");
q.setInteger(0, object1.id);
int count = q.executeUpdate();


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 23, 2006 10:40 am 
Regular
Regular

Joined: Mon May 22, 2006 2:30 pm
Posts: 74
Thanks for the reply. Yes, I understand that part of it. I was unsure about the precise syntax for referring to a property embedded within a composite id. The problem with using HQL is that you lose the benefit of cascading deletes, etc., that are provided when you work via the persistent objects and collections.

What I am discovering is that Hibernate is much more useful for adding and updating persistent objects than it is for deleting object hierarchies with collections of objects. I have decided to use database triggers to cascade deletes. I simply don't see any advantage to using Hibernate for deleting anything. This will, of course, bypass the optimistic locking, but that really doesn't matter so much when you are deleting, as opposed to reading and updating.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 23, 2006 12:14 pm 
Expert
Expert

Joined: Tue Apr 25, 2006 12:04 pm
Posts: 260
Code:
// if you have enabled cascading delete in your mapping files
// like cascade="on-delete-orphan" below code should work
Class2 parentObject = (Class2) session.get( Class2.class, compositeKey );
// if you want to delete parent and child objects
session.delete( parentObject );
// if you want to delete only children
// a variation of below statement should work
parentObject.setChildrenSet( new HashSet() );
session.saveOrUpdate( parentObject );


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 23, 2006 1:42 pm 
Regular
Regular

Joined: Mon May 22, 2006 2:30 pm
Posts: 74
Thanks for the reply. I understand that Hibernate will cascade deletions. It does not seem to do this in a manner that is nearly as efficient as using the database itself to cascade the deletions. I have probably not tried every possible technique within Hibernate to delete persistent hiercharchies, but I have tried several and they all either result in unnecessary SELECT statements, or issue multiple DELETE statements in cases where a single DELETE statement could conceivably be used. I am dealing with complex hierarchies with layers of one-to-many relationships, potentially involving thousands of actual persistent objects/rows. This will be running in a clustered J2EE application server environment with a very heavy transactional load. Deletions must be as efficient as possible so as not to consume more resources than absolutely necessary.


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.