tags:

views:

50

answers:

4

I'm trying to implement a repository method for removing entities using only primary key, mainly because from a webapp I usually only are aware of the primary key when invoking a "delete request" from a web page.

Because of the ORM, the option today is to get the entity from the database, and then deleting it, which gives me an extra roundtrip.

I could use HQL delete, but since I want to create a generic delete method for all entities, that won't fly unless I use reflection to find out which field that is the primary key (doable, but doesn't feel correct).

Or is it in the nature of NHibernate to need the entity in order to correctly handle cascades?

I tried this approach, with the assumption that it would not load the entity unless explicitly necessary, however haven't had time to test it yet. Maybe someone can shed some light on how this will be handled?

var entity = session.Load<T>( primaryKey );
session.Delete( entity );

EDIT: Have now tested it and it seems that it still does a full select on the entity before deletion.

+1  A: 

nHibernate is an O(bject)RM. I agree with you that it probably needs the objects to resolve dependencies.

You can of course use direct ADO.Net calls to delete your objects. That presents its own problems of course since you'll have to take care of any cascading issues yourself. If you do go down this road, don't forget to evict from the nHibernate session whatever objects you delete using this method.

But, if this delete is in a really sensitive part of your system, that might be the way to go.

I'd make 100% sure though that this is the case. Throwing away all the nHibernate gives you because of this would not be wise.

I get the sense you know this, and you're looking for a strictly nHibernate answer, and I don't think it exists, sorry.

CubanX
+1  A: 

Disclaimer: I am not able to test it as of now. But won't following thing help:

Person entity = new Person();
entity.Id = primaryKey;
session.Delete( entity );

Don't load the entity but build your entity having just the primary key. I would have loved to test it but right now my environment is not working.

Pradeep
That might work, but it might refuse to delete an object that isn't associated with the session. Problem for me beeing that not all entities has .Id as their primary key, I would need to reflect in order to find out which is what, not a pretty solution I think. Thanks for the suggestion though.
jishi
+2  A: 

Load may return a proxy object but it isn't guaranteed. Your mapping may contain cascade deletes that will force NHibernate to load the object from the database in order to determine how to delete the object and its graph.

I would implement this using Load as you are doing. For some objects NHibernate may not need to do a select first. In cases where it does, that's the [usually] trivial price you pay for using an o/r mapper.

Jamie Ide
I have been trying to figure out when it will return a proxy object. Do you know if it only returns proxies for classes that are defined as "lazy"?
jishi
I don't know, but my guess is that it will load the object if the mapping contains any cascade settings. This is a nice feature -- you don't need to worry about cleaning up related objects. I would live with this behavior unless there was a performance problem. Loading objects by primary key is typically a very fast operation.
Jamie Ide