grailsInvas0r
grailsInvas0r

Reputation: 655

grails insert into DB without saving, why?

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

Answers (3)

Burt Beckwith
Burt Beckwith

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

jenk
jenk

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

Dónal
Dónal

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

Related Questions