2014-11-06 66 views
1

我有一個Spring Boot應用程序,通過JPA批註配置了許多實體。對於特定類型的新實體,我運行幾個查詢來確定是否存在基於日期字段的舊條目。這部分工作正常。但是,我還沒有在目標對象的任何位置調用存儲庫上的save()。雖然選擇的查詢執行我似乎是自動沖水......Spring JPA在調用保存之前自動插入Entity。這怎麼能被阻止?

2014-11-06 12:05:46.617 DEBUG 5070 [clientInboundChannel-10] --- org.hibernate.engine.spi.ActionQueue  : Executing identity-insert immediatel 
2014-11-06 12:05:52.647 DEBUG 5070 --- [boundChannel-10] org.hibernate.SQL      : insert into target_object_table... 
2014-11-06 12:05:52.647 DEBUG 5070 [clientInboundChannel-10] --- org.hibernate.SQL      : insert into ftarget_object_table... 

的問題是,因爲我並沒有提出這項平齊我對象的版本仍具有0因此,一個ID在以後的在@Transaction中指向我調用repository.save(targetObject)並最終以兩個保存在數據庫中。

在研究通過谷歌似乎有兩件事可能會解決這個問題,但我不是100%確定如何配置他們與「春季啓動」/「jpa」。

1)我猜測,因爲我的對象具有@Entity符號,它會自動附加在實例化時間。有沒有簡單的方法來防止這種情況?我必須顯式調用實體管理器上的detach()嗎?

2)是否有一個application.properties設置將刷新模式更改爲提交或註釋@Query上的選項來更改每個查詢級別的提交模式?

+0

我認爲你對交易的理解有問題,需要刷新和保存。在Spring聲明式事務管理中,您幾乎不必調用flush,但在事務邊界結束時(由@Transaction標記 - 考慮父/子方法調用),Spring事務管理將提交事務。沖洗時間往往是不確定的,你不應該知道什麼時候,除了它總是發生在交易結束 – gerrytan 2014-11-06 22:26:03

回答

0

第一個問題)

我猜測,因爲我的對象有@Entity標記它會自動被安裝在實例化時。

這是錯誤的,當您創建一個新的類,它被註釋爲@Entity它不會自動成爲JPA(休眠)實體。 - 您需要調用EntityManager.persist(或某些Spring-Data-JPA函數)使其成爲JPA(Hibernate)實體。

+0

好吧。很公平。所以這引發了問題...... Spring JPA如何刷新並插入一個我從來沒有調用過的對象,並且ID爲null?我在嘗試插入之前也嘗試過查詢對象,而查詢結果集沒有新對象,因此查詢只是敲擊數據庫,並未在會話的任何緩存條目中進行合併。 – 2014-11-06 19:28:48

+0

@Scott Delap:如何讓Spring JPA知道這個對象?您能否發佈用於創建此對象的代碼? – Ralph 2014-11-07 07:07:06

1

因此,在Hibernate插入代碼的一些深入調查和設置斷點後,我確定我確實有兩個有效請求在同一秒進入。這不是我期望從Web應用程序層獲得的行爲,因此在提問時我沒有沿着這條調試路線走下去。由於我的事務未配置爲鎖定讀取,所以兩個事務方法都可以針對數據庫對日期的現有條目進行檢查(未找到它,然後執行插入操作)。修復Web層後(這是一個AngularJS問題),問題就消失了。

相關問題