2010-05-10 45 views
4

與JPA工作/休眠在OSIV Web環境是推動我瘋了。)合併/重新安裝在JPA /休眠而不更新DB

以下情形:我有一個通過JPA加載一個實體A和有一個B實體的集合。那些B實體有一個必填字段。

當用戶通過按web應用程序中的鏈接向A添加新的B時,該必填字段未設置(因爲沒有合理的默認值)。

在下一個http請求時,OSIV過濾器嘗試合併A實體,但是由於Hibernate抱怨新B沒有設置必填字段,因此失敗。

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value 

閱讀JPA規範,我看不出有任何跡象表明這些檢查在合併階段要求(我沒有交易活動)

我不能讓B的A和唯一的外集合當用戶按下「保存」(aka entitymanager.persist())作爲保存按鈕所不知道的地方時,將它們添加到A僅僅是關於A.

另外A和B只是示例,我有類似的東西在各地..

任何想法?其他JPA實現在這裏的行爲是否相同?

在此先感謝。

回答

2

我做了很多閱讀和測試。這個問題來自我對JPA/Hibernate的誤解。 merge()總是對數據庫產生影響,並且還爲實體安排更新。在JPA規範中我沒有發現任何提及,但'Java Persistence with Hibernate'一書提到了它。

通過查看EntityManager(和會話作爲回退)API,它看起來好像沒有辦法只將實體分配給當前的持久性上下文而沒有調度更新。畢竟,我想要的是導航對象圖,根據需要更改屬性,並稍後觸發更新(如果需要,將進行版本檢查)。我認爲每個使用ORM的Web應用程序都必須這樣做?

的基本工作流程我「在尋找:

  1. 負載從DB一個實體(或創建一個新的)
  2. 讓實體(及其所有關聯成爲分離(作爲EntitManager關閉在HTTP請求結束)
  3. 下一個HTTP請求再次出現時,工作與這些對象,導航樹,而不必擔心LazyInitExceptions的
  4. 呼叫仍然存在)
  5. 在1-3所做的所有更改的方法

隨着春季OSIV過濾器與來自wicket的IModel實現相結合,我以爲我已將其歸檔。

我主要看2種可能的方式出來的:

一)加載實體和進入某個頁面(使用情況)時所需的所有關聯,讓他們變得分離,添加/根據需要改變它們幾個http請求的過程。當用戶啓動一個保存(驗證器將確保一個有效的狀態)並重新連接它們並將它們提交給數據庫。b)使用當前設置,但要確保所有新添加的實體都設置了所有必需的字段(可能使用了一些嚮導組件)。我仍然會對每個merge()的數據庫進行所有更新,但希望數據庫管理員不會實現;)

其他人如何在Web環境中使用JPA?對我來說還有其他選擇嗎?