Can I disable automatic updating of dirty objects?

847 views
Skip to first unread message

trul...@googlemail.com

unread,
Mar 23, 2009, 11:43:04 AM3/23/09
to nhibernate-development
I'll describe my specific situation, but this is also a general
question around the subject.

I'm developing a web application, and I'm using a UnitOfWork to create
me a session/tx on begin_request and it flushes/commits on
end_request.

On an edit screen for one of my persisted objects, I get the object
from NH, set the properties with the POSTed data from the edit form,
then validate the object to make sure no business rules are violated.
In pseudo code:

var person12 = Session.Linq<Person>().Query().Where(x => x.Id = 12);

person12.Age = int.parse(form["Age"]);

if(person12.Age >= 18)
Session.Update(person12);
else
throw new ValidationException("You must be at least 18");


The problem is that if the validation fails, the person object is
still saved when the transaction is committed on end_request.

What should I do about this?

It seems very strange to me that dirty objects should get saved
without me telling the session to update it. Can I just turn this
behaviour off? If so, how? It seems strange that there is a
Session.Update(object) method, if you cant turn it off.

If i cant turn it off, what am I supposed to do? I've had suggestions
of Evict()ing the object or calling setReadOnly, but they feel like
hacks. I don't want to rollback the transaction, because what if ive
got other updates pending that i do want to commit?

Am I missing some concept which is why automatic dirty object updating
feels wrong to me?

Thanks for any advice,

Andrew

Will Shaver

unread,
Mar 23, 2009, 12:08:49 PM3/23/09
to nhibernate-...@googlegroups.com
You have a couple of options here:

a) evict the item
b) use long running sessions, and make the user fix the problem before
committing the transaction. Won't work in an over 18 case, but will
work for bad formatted email addresses
c) change the entity back to the way it was prior to the request

hmm.. I'm sure there are others. I'd look into the long running
sessions. If you're using rhino tools, there's even a way to have
multiple long running sessions concurrently for the same user.

-Will

trul...@googlemail.com

unread,
Mar 23, 2009, 12:16:23 PM3/23/09
to nhibernate-development
These all involve me putting NH specific code into my domain model,
which I don't want to do.

I expect it to save if i tell it to, and not if i dont, why is this so
difficult?

Thanks

Andrew


On Mar 23, 4:08 pm, Will Shaver <will.sha...@gmail.com> wrote:
> You have a couple of options here:
>
> a) evict the item
> b) use long running sessions, and make the user fix the problem before
> committing the transaction. Won't work in an over 18 case, but will
> work for bad formatted email addresses
> c) change the entity back to the way it was prior to the request
>
> hmm.. I'm sure there are others. I'd look into the long running
> sessions. If you're using rhino tools, there's even a way to have
> multiple long running sessions concurrently for the same user.
>
> -Will
>
> On Mon, Mar 23, 2009 at 8:43 AM, trull...@googlemail.com

Will Shaver

unread,
Mar 23, 2009, 12:21:03 PM3/23/09
to nhibernate-...@googlegroups.com
Two thoughts here:

1) Long running transactions don't/shouldn't require domain code. Your
domain throws an exception, something else catches it and doesn't
commit the transaction. You don't have to discard the transaction,
just make the user fix it before save.

2) If you REALLY want the "don't save if I don't say so" then evict
items right after loading them. Of course then lazy loading etc won't
work....

-Will

trul...@googlemail.com

unread,
Mar 23, 2009, 12:28:01 PM3/23/09
to nhibernate-development
No, not as much as the other 2 options, but long running transactions
don't really fit the web model, do they?

A user might not want to fix the problem, they may just abandon, you
cant handle this other than with a timeout.
What if i've got changes I do want to save, and some i dont?

This behaviour makes absolutely zero sense to me. Why on earth would
you want your ORM to save things you haven't asked it to??

Andrew


On Mar 23, 4:21 pm, Will Shaver <will.sha...@gmail.com> wrote:
> Two thoughts here:
>
> 1) Long running transactions don't/shouldn't require domain code. Your
> domain throws an exception, something else catches it and doesn't
> commit the transaction. You don't have to discard the transaction,
> just make the user fix it before save.
>
> 2) If you REALLY want the "don't save if I don't say so" then evict
> items right after loading them. Of course then lazy loading etc won't
> work....
>
>  -Will
>
> On Mon, Mar 23, 2009 at 9:16 AM, trull...@googlemail.com

Fabio Maulo

unread,
Mar 23, 2009, 12:56:56 PM3/23/09
to nhibernate-...@googlegroups.com


I'm developing a web application, and I'm using a UnitOfWork to create
me a session/tx on begin_request and it flushes/commits on
end_request.

You have implemented your own UoW or you are simply using the NH-session ?
 
On an edit screen for one of my persisted objects, I get the object
from NH, set the properties with the POSTed data from the edit form,
then validate the object to make sure no business rules are violated.
In pseudo code:

var person12 = Session.Linq<Person>().Query().Where(x => x.Id = 12);

person12.Age = int.parse(form["Age"]);

if(person12.Age >= 18)
   Session.Update(person12);
else
   throw new ValidationException("You must be at least 18");


The problem is that if the validation fails, the person object is
still saved when the transaction is committed on end_request.

Sure ? Why you are calling session.Update before validate the entity ?
Or why you are not using a validation in a NH-Event listener ?
 
What should I do about this?

It seems very strange to me that dirty objects should get saved
without me telling the session to update it. Can I just turn this
behaviour off? If so, how? It seems strange that there is a
Session.Update(object) method, if you cant turn it off.

The UoW (nh-session) is dirty when at least one of his object is dirty.
You can turn-off the auto-flush and manage the flush by your self.

The other option is turn-off the dirty-check overriding the default listener.

--
Fabio Maulo

Stephen Bohlen

unread,
Mar 23, 2009, 1:29:25 PM3/23/09
to nhibernate-...@googlegroups.com
Should this thread move to nhusers...?  Seems overloaded to have this conversation here...

http://groups.google.com/group/nhusers
--
Steve Bohlen
sbo...@gmail.com
http://blog.unhandled-exceptions.com
http://twitter.com/sbohlen

trul...@googlemail.com

unread,
Mar 24, 2009, 5:31:13 AM3/24/09
to nhibernate-development
Hi Fabio,

Thanks for your help, you raised a couple of points which I think are
probably the answers I'm looking for...

>
> > The problem is that if the validation fails, the person object is
> > still saved when the transaction is committed on end_request.
>
> Sure ? Why you are calling session.Update before validate the entity ?
> Or why you are not using a validation in a NH-Event listener ?

I think moving my validation to an NH event could solve this issue for
me, I will look into this

>
> The UoW (nh-session) is dirty when at least one of his object is dirty.
> You can turn-off the auto-flush and manage the flush by your self.
>
> The other option is turn-off the dirty-check overriding the default
> listener.
>
> --
> Fabio Maulo

Can you give me some pointers on how to override the default dirty
check listener, this sounds like something I might want to try...

Thanks

Andrew
Reply all
Reply to author
Forward
0 new messages