我在Grails中發現了一些奇怪的東西。grails插入到數據庫而不保存,爲什麼?
我創建一個對象,如:
User a = new User()
a.setName("test")
a.save()
之後
我呼叫的方法例如SETACTIVE喜歡:
a.setActive(true)
和切勿調用save(),但它被保存在數據庫中。我不知道爲什麼?!我認爲這是危險的。對此有何建議?
非常感謝,
馬爾科
我在Grails中發現了一些奇怪的東西。grails插入到數據庫而不保存,爲什麼?
我創建一個對象,如:
User a = new User()
a.setName("test")
a.save()
之後
我呼叫的方法例如SETACTIVE喜歡:
a.setActive(true)
和切勿調用save(),但它被保存在數據庫中。我不知道爲什麼?!我認爲這是危險的。對此有何建議?
非常感謝,
馬爾科
服務方法執行後(在事務性= true的情況下)grails保存所有更改與域/持久對象和刷新休眠會話。
重定向在控制器操作中的行爲相同。
要回滾更改 - 拋出RuntimeException。
它關閉會話之前,因爲Hibernate會自動保存所有待定的更新持久對象。這就是Hibernate的工作原理。
如果您通過調用.save()
來指示您希望持久化一個對象,Hibernate會假定您還希望保存該對象的任何後續更改。如果您不希望該更新持續存在,則在撥打a.setActive(true)
時我看不到這一點。
Grails註冊一個「OpenSessionInView」攔截器,它在每個請求開始時打開Hibernate會話,並在完成後刷新並關閉它。這主要用於懶加載的集合。如果沒有打開的會話,加載實例後會立即斷開連接,因此試圖訪問集合會引發異常。通過使會話保持活動狀態,可以解決集合。
默認情況下,Hibernate會在刷新過程中自動推送持久化實例中的更改,因爲在請求結束時刷新OSIV攔截器,所以任何「髒」實例(如您的User實例)都會將其更改推送到數據庫。
要解決這個問題,您可以使用read()
方法來加載現有的實例,如果您只想暫時修改它,例如用於在GSP中呈現,但不希望更改自動保留。
這不適用於你的情況,因爲你沒有得到一箇舊的實例,你正在創建它。在你的情況下,只需在保存之後調用a.discard()
,並將它從Hibernate會話中斷開,並且在發生刷新時Hibernate將不會推送任何內容。
但是,如果丟棄()也不起作用。這裏是我在做什麼: 'contactInstance.discard() contactInstance.properties = params' 但是在執行服務方法之後,即使不調用任何保存方法,這些更改也會反映在數據庫中 –