I have prepared simple controller action to test behaviour related with unexpected commiting changes to datatbase:
def testSimple() {
Product p = Product.findById(1);
p.name = "test doneee"
//p.save flush:true
respond p
}
The changes are persisted in database even the save()
has not been called. How to avoid saving entity without calling save()
?
Grails registers an OpenSessionInView interceptor which starts a Hibernate Session and the beginning of each request, and flushes and closes it at the end of the request. This is primarily done to allow lazy-loaded one-to-many instances and many-to-one collections to load on demand. One side effect is what you're seeing, that changing a persistent instance causes the changes to get pushed to the database even without a save()
call. This is because changing it marks it dirty, and Hibernate discovers all dirty objects during the flush and pushes the changes to the database.
To avoid changes like this from being persisted, use the http://grails.org/doc/latest/ref/Domain%20Classes/discard.html method to detach it from the Session.
p.s. Unrelated, but you should use get
instead of findById
, since get
does the same thing but has much better caching behavior.