2011-11-23 80 views
1

我在Grails中發現了一些奇怪的東西。grails插入到數據庫而不保存,爲什麼?

我創建一個對象,如:

User a = new User() 
a.setName("test") 
a.save() 
之後

我呼叫的方法例如SETACTIVE喜歡:

a.setActive(true) 

切勿調用save(),但它被保存在數據庫中。我不知道爲什麼?!我認爲這是危險的。對此有何建議?

非常感謝,

馬爾科

回答

3

服務方法執行後(在事務性= true的情況下)grails保存所有更改與域/持久對象和刷新休眠會話。
重定向在控制器操作中的行爲相同。
要回滾更改 - 拋出RuntimeException。

2

它關閉會話之前,因爲Hibernate會自動保存所有待定的更新持久對象。這就是Hibernate的工作原理。

如果您通過調用.save()來指示您希望持久化一個對象,Hibernate會假定您還希望保存該對象的任何後續更改。如果您不希望該更新持續存在,則在撥打a.setActive(true)時我看不到這一點。

6

Grails註冊一個「OpenSessionInView」攔截器,它在每個請求開始時打開Hibernate會話,並在完成後刷新並關閉它。這主要用於懶加載的集合。如果沒有打開的會話,加載實例後會立即斷開連接,因此試圖訪問集合會引發異常。通過使會話保持活動狀態,可以解決集合。

默認情況下,Hibernate會在刷新過程中自動推送持久化實例中的更改,因爲在請求結束時刷新OSIV攔截器,所以任何「髒」實例(如您的User實例)都會將其更改推送到數據庫。

要解決這個問題,您可以使用read()方法來加載現有的實例,如果您只想暫時修改它,例如用於在GSP中呈現,但不希望更改自動保留。

這不適用於你的情況,因爲你沒有得到一箇舊的實例,你正在創建它。在你的情況下,只需在保存之後調用a.discard(),並將它從Hibernate會話中斷開,並且在發生刷新時Hibernate將不會推送任何內容。

+0

但是,如果丟棄()也不起作用。這裏是我在做什麼: 'contactInstance.discard() contactInstance.properties = params' 但是在執行服務方法之後,即使不調用任何保存方法,這些更改也會反映在數據庫中 –

相關問題