GORM auto flush when request ends without calling save

余生颓废 提交于 2019-12-24 00:36:17

问题


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()?


回答1:


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.




回答2:


This can make your order of operations a nightmare. [See this SO post][1] Grails GORM auto update issue

It makes using the getPersistentValue() method on an object scary in a large application context. If there is a database call somewhere in the chain, even if it is totally unrelated, your persisted values will change.

I did find that marking database calls as readonly prevents trigger of auto save. For example in a a service

import org.springframework.transaction.annotation.Transactional

  class TestService{

   @Transactional(readOnly = true)
   def queryDatabase(){
      //this operation won't trigger auto updates now, yay
   }

  }

But not all cases would be read only, and again in a large context your code could go ka-put if another developer doesn't explicitly set readonly. But that's grails for you, complexity through convention



来源:https://stackoverflow.com/questions/19617470/gorm-auto-flush-when-request-ends-without-calling-save

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!