-->
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.  [ 9 posts ] 
Author Message
 Post subject: Deleting with ICriteria
PostPosted: Sun Jul 03, 2005 7:34 pm 
Newbie

Joined: Mon Jun 20, 2005 4:44 pm
Posts: 2
Location: New Jersey
Hi, I'm wondering if anyone has experience with deletions using ICriteria instances.

What I mean is, instead of doing something like:

Code:
ISession.Delete("FROM MyTable myTable WHERE....");


do this:

Code:
ICriteria criteria = ISession.CreateCriteria(typeof(MyTable));
criteria.Add(<expression here>);
criteria.Add(<another expression>);
ISession.Delete(criteria.Expression.ToSqlString(<args here>).ToString());


This would be helpful for situations where the delete becomes complex and may have several subparts (so instead of using System.Text.StringBuilder to build the query, we can use ICriteria).

The problem is that I can't seem to figure out how the ToSqlString() works. Specifically, I can't figure out where I'm supposed to get an instance of ISessionFactoryImplementor from :?:

Are there other possible ways to do a delete using ICriteria that anyone has had succss with?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 04, 2005 4:14 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Delete doesn't use SQL (only HQL), so your approach won't work anyway. Delete actually first executes the query to load the objects and then deletes them one-by-one, so you might as well do it yourself - execute the query and then traverse the result list and delete each object.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 05, 2005 9:58 am 
Newbie

Joined: Mon Jun 20, 2005 4:44 pm
Posts: 2
Location: New Jersey
sergey wrote:
Delete doesn't use SQL (only HQL), so your approach won't work anyway. Delete actually first executes the query to load the objects and then deletes them one-by-one, so you might as well do it yourself - execute the query and then traverse the result list and delete each object.


:shock:

Seriously?!?

Basically, I'm building a simple web based log viewer to for log4net output where users can delete log entries. There may be hundreds-thousands of log entries each month that a user wants to delete (I've restricted the users to a month-by-month view to reduce loading times). So if I'm understanding this correctly, ISession.Delete(<string>) actually *loads* all of the data first and *then* issues the delete, even though I haven't specified the type to load?

Seems awfully inefficient...is there a batch delete option or some more efficient way of doing this with NHibernate?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 05, 2005 12:36 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
No, NHibernate doesn't have a batch delete feature. The reason it's deleting objects one-by-one is it needs to handle cascades, interceptions and other such things. I believe Hibernate 3 did some work regarding batch deletes, but even if so, it will be quite a long time before this is ported to NHibernate.

So I think for now you can only use direct SQL to delete the entries...


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 06, 2005 10:31 am 
Regular
Regular

Joined: Thu May 12, 2005 10:12 am
Posts: 71
Location: Buenos Aires, Argentina
I wanted to jump into the discussion and add a question then:

what is the most performant way to delete a collecition of objects? I found that when I delete and object the cascade gets fired one by one. If I load the object and do a IList.Clear() will make nhibernate realize it has to do a batch delete?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 06, 2005 1:56 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
The most performant way is probably to use direct SQL. NHibernate does use batch deletes when deleting a persistent collection, but I don't understand what IList you refer to. If you mean a list of query results, then it's not a persistent collection, but a plain ArrayList, and NHibernate can't detect any changes to it.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 06, 2005 5:58 pm 
Regular
Regular

Joined: Thu May 12, 2005 10:12 am
Posts: 71
Location: Buenos Aires, Argentina
No, I'm mean a entity collection.

What I'm seeing is that I have a kind of relationship akin to Order and OrderItem mapped with a Bag. When I issue a deleteById (with HQL) with Order and look at the log I see multiple deletes for each orderitem.

I have set cascade="all-delete-orphan". I'm surely doing something wrong, but don't know what.

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 12, 2005 2:16 pm 
Regular
Regular

Joined: Mon May 16, 2005 2:15 pm
Posts: 59
roniburd wrote:
No, I'm mean a entity collection.

What I'm seeing is that I have a kind of relationship akin to Order and OrderItem mapped with a Bag. When I issue a deleteById (with HQL) with Order and look at the log I see multiple deletes for each orderitem.

I have set cascade="all-delete-orphan". I'm surely doing something wrong, but don't know what.

Thanks!


No, I see the same thing too. I expected a:

DELETE FROM Child WHERE ParentID = @ParentID

But, it issues a delete for each child record, then for the parent.

I haven't looked at the code but I assume this is because NHibernate knows about objects and not data. It traverses the object graph to the lowest child in the hierarchy then deletes each item in any collections it contains going up the tree generating the delete for each object as it climbs up the tree.

However, what I don't understand is why it issues each command seperately rather than batching them in on command. Seems like alot of traffic could be avoided by sending all the generated deleted in a single command to SQL. Perhaps all back ends don't support this, I don't know. Seems like a db feature the dialect could enumerate.

BOb


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 07, 2005 8:28 pm 
Senior
Senior

Joined: Sat Sep 10, 2005 3:46 pm
Posts: 178
I was having terrible performance on a delete operation so I decided to do a cascase delete with a trigger but now I am getting a weird error. When I try to delete the entity I get this error from NHibernate:

Duplicate identifier in table for RemoteNet.Northrop.IbisWork.Domain.Model.SubStep: 2172


Stack Trace:


[HibernateException: Duplicate identifier in table for RemoteNet.Northrop.IbisWork.Domain.Model.SubStep: 2172]
NHibernate.Persister.AbstractEntityPersister.Check(Int32 rows, Object id)
NHibernate.Persister.EntityPersister.Delete(Object id, Object version, Object obj, ISessionImplementor session)
NHibernate.Impl.ScheduledDeletion.Execute()


Any clues as to why this is happening and what table it is referring to. The sql statements that get executed all look good.


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