2013-04-08 164 views
3

考慮下面的代碼:爲什麼我的GORM對象不保存到數據庫?

if (!serpKeyword) { 
    serpKeyword = new SerpKeyword(
      keyword: searchKeyword, 
      geoKeyword: geoKeyword, 
      concatenation: concatenation, 
      locale: locale 
    ) 
    serpKeyword.save(flush: true, failOnError: true) 
} 

serpService.submitKeyword(serpKeyword, false) 

這裏的submitKeyword方法:

@Transactional(propagation = Propagation.REQUIRES_NEW) 
boolean submitKeyword(keywordToSubmit, boolean reset) { 
    def keyword = SerpKeyword.get(keywordToSubmit.id) 

當我打電話serpKeyword.save不會引發錯誤,但是當我進入submitKeyword方法,SerpKeyword.get(keywordToSubmit.id)返回null。有什麼可以防止這個保存?

編輯

更改REQUIRES_NEWREQUIRED似乎這樣的伎倆。這是我認爲正在發生。

調用serpService.submitKeyword的代碼位於服務方法中。據我所知,服務方法的默認傳播策略爲REQUIRED。由於這一切的數據庫寫入操作在一個事務的範圍內發生的事情,寫操作在數據庫中排隊,但直到交易完成對數據庫並沒有真正執行,根據docs

注意,沖洗與提交交易不同。如果 您的操作是在事務上下文中執行的,則刷新 將執行SQL更新,但數據庫會將更改保存在其 事務隊列中,並且僅在事務 提交時完成更新。

我們稱之爲serpService.submitKeyword之前我們的交易實際完成。該方法開始一個全新的交易,其中serpKeyword不可用。將其更改爲REQUIRED的作品是因爲我們現在在我們的父交易的上下文中操作。

+0

這可能是因爲您有一些空域或無效的域字段。嘗試將所有域字段設置爲一些有效值。 – 2013-04-08 18:24:36

+0

@ToddMurray:我設置了'failOnError'屬性;如果我的記錄無效,是否會拋出異常?另外值得注意的是:如果我在'withNewTransaction'塊中創建了我的'SerpKeyword',它會保存到數據庫中,但是之後記錄無法在路上更新,可能是由於鎖定問題。 – Samo 2013-04-08 18:33:11

+1

你確定你的代碼通過了'serpKeyword.save()'嗎?如果你在調試中檢查傳遞給服務的實例,你可以看到id不爲空? – 2013-04-08 23:38:35

回答

0

我認爲堆棧的某些部分是懶惰的。我已經遇到了Hibernate的這種行爲,如果這就是你正在使用的。我不知道這是經過批准的動作,但你可以調用submitKeyword像這樣前清除會話:

long keywordId = serpKeyword.id 
SerpKeyword.withSession{it.clear()} 
serpService.submitKeyword(keywordId, false) 

,然後更改方法:

@Transactional(propagation = Propagation.REQUIRES_NEW) 
boolean submitKeyword(keywordId, boolean reset) { 
    def keyword = SerpKeyword.get(keywordId) 

然後我敢打賭,.get()將工作。如果您需要在會話中使用其他對象。你需要通過存儲他們的id和.get()來解除他們。

+0

請參閱我的編輯。我的發現與你的建議一致嗎? – Samo 2013-04-25 19:39:43

相關問題