Reputation: 655
I found something strange in Grails.
I create an object like:
User a = new User()
a.setName("test")
a.save()
after that I call a Method e.g. setActive like:
a.setActive(true)
and DON'T call save() but it is saved in the database. I don't know why?! I think this is dangerous. Any suggestions on this?
Thanks a lot,
Marco
Upvotes: 1
Views: 2344
Reputation: 75681
Grails registers an "OpenSessionInView" interceptor that opens a Hibernate session at the beginning of each request, and flushes and closes it after it's finished. This is primarily there for lazy-loaded collections. If there wasn't an open session, after loading the instance it would immediately become disconnected, so trying to access a collection would throw an exception. By keeping the session active, the collections can be resolved.
By default Hibernate automatically pushes changes in persistent instances during a flush, so since the OSIV interceptor flushes at the end of the request, any "dirty" instances like your User instance will have their changes pushed to the database.
To get around this, you can use the read()
method to load an existing instance if you only want to modify it temporarily, e.g. for rendering in the GSP, but don't want changes auto-persisted.
This won't work in your case since you're not getting an old instance, you're creating it. In your case just call a.discard()
after saving and that will disconnect it from the Hibernate session, and Hibernate won't have anything to push when the flush happens.
Upvotes: 6
Reputation: 1043
After execution of service methods (in case of transactional = true) grails save all changes with domain/persist objects and flush hibernate session.
The same behaviour of Redirect in controller action.
To rollback changes - throw RuntimeException.
Upvotes: 3
Reputation: 187399
Because Hibernate automatically saves all pending updates to persistent objects before it closes the session. This is just how Hibernate works.
If you indicate that you want an object to be persistent by calling .save()
on it, Hibernate assumes that you also want any subsequent changes to that object to be saved. I don't see the point in calling a.setActive(true)
if you don't want that update to be persisted.
Upvotes: 2