2016-12-02 169 views
0

RaceRegistration域已嵌入raceParticipant,raceParticipant有一個字段bibNumber,它是Integer。爲什麼save()不保存數據並保存(flush:true)是必需的?

我有一個方法,用於清空註冊的所有bibNumbers,但沒有刷新:true保存,無效的圍兜不起作用。圍兜沒有設置爲空。

def nullifyBibNumbers(Long id){ 

     ... 

     def regss = RaceRegistration.createCriteria().list(){ 

      eq('compositeEvent', event) 

     } 



     regss.each{ r -> 

      r.raceParticipant.bibNumber = null 
      r.save() 
     } 


     render "Bibs resetted!" 


    } 

如果我添加flush:true,則圍兜被設置爲null。

regss.each{ r -> 

     r.raceParticipant.bibNumber = null 
     r.save(flush: true) 
    } 

我想知道爲什麼你需要flush以便將值設置爲null?我猜測問題是關於我如何使用createCriteria()獲取註冊列表。我很感謝我面臨的這個困境。謝謝!

回答

1

正如您可能已經想出的那樣,save(flush: true)強制Hibernate將任何掛起的更改寫入數據庫。如果沒有顯式刷新,您將依賴Hibernate事務來在事務提交時自動刷新。

只有顯式刷新功能適用於您的原因是因爲您不在事務中調用save()

最簡單的修復方法是創建一個Grails服務,將nullifyBibNumbers()放入其中,並使服務transactional。這將導致nullifyBibNumbers()被封裝在一個事務中,以便您可以在沒有顯式刷新的情況下使用save()

如果nullifyBibNumbers()已經在服務中,您可以將@Transactional添加到服務類中,只要記住它會使所有方法(可能只是公共方法)事務性。話雖如此,您可以在方法上使用@NotTransactional來禁用事務。

0

您的域對象中的值爲空。但是,你在談論數據庫中的空值,我猜? 它應該沒關係。這是基本的ORM。作爲一名開發人員,你不關心刷新完成的時間。通常這將在交易結束時進行。然後,ORM將立即清除該事務的所有更改。 它在事務過程中對所謂的第一級緩存起作用,並且試圖避免直到明確請求(flush:true)或必需(事務結束)之前才轉到db。

+0

爲什麼save()不保存數據並flush:true是必需的?由於大量的記錄,我無法使用flush:true。 – kofhearts

+0

就像我剛纔所說:save()**將**保存數據,但不一定立即。請注意,我們正在討論這裏的更新,數據庫中已存在數據。新實例(即DB插入)的保存將立即生效。 –

+0

我在方法完成後檢查數據。方法完成後應該有數據嗎? – kofhearts

0

沒有使用

save(flush: true) 

對象不會立即堅持。

您可以按照documentation link和看到以下信息:

的保存方法通知實例 應保存或更新的持久化上下文。除非使用flush參數,否則該對象將不會被立即保留 。

與您遇到的null問題相關,請確保滿足以下條件。

如果驗證失敗並且實例不是持久性,或實例本身如果成功,則save方法返回null。

您不需要flush以便將值設置爲null。 刷新只關心數據庫的快速更新。

+0

謝謝,但仍然沒有回答我的問題,爲什麼save()不保存數據,只有刷新:true將保存數據,即設置參數編號爲空。 – kofhearts

+0

默認情況下,GORM類配置爲樂觀鎖定,這是Hibernate的一項功能,它涉及在表中存儲遞增版本。當Hibernate會話刷新時,該值僅在數據庫中更新。潛入hibernate中,使用flush:true將刷新與事務相關的會話。當使用inly save()時情況並非如此 – Rotem

0

好吧我使用HQL而不是域保存解決了這個問題。不過,我會明白爲什麼save()沒有工作並保存(flush:true)保存數據。謝謝!

RaceRegistration.executeUpdate("update RaceRegistration set raceParticipant.bibNumber = null where compositeEvent.id = :ev", [ev: id])