2012-06-25 91 views
4

我正在編寫一個程序來運行數十萬相關類型的實體的批處理過程。我原本是通過一次持續的單筆交易來完成這項工作的。這看起來非常慢,所以我嘗試按照http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html中描述的方式進行一些天真的批量更新,其中更長的事務和偶爾的清空+清除。我遇到了一些ConstraintViolationException,因爲我有一些獨特的字段限制。但是,我不確定如何檢查現有的實例;我目前有一個列出衝突的標準,但它似乎不返回在同一個事務中保存或更新的實體。Hibernate批量插入/更新constraintviolationexception

一個虛構的例子可能會有幫助:
實體家庭,人,名
家庭有很多人(一對多)
人有很多名字,不同的人可以有相同的名稱。 (多對多)

我的更新包括堅持一個家庭以及其人員和名稱,但我不知道如何去除名稱(可能與數據庫中的現有名稱或同一更新批處理中的其他名稱相沖突)。我可以在Hibernate之外追蹤新實體的唯一約束字段,但我認爲這可能不是必需的。是否有任何內置的方式來檢查數據庫和未提交的更改中的重複項?我看到Hibernate batch updates with constraintviolationexception,但我沒有在正常的代碼路徑中使用異常。謝謝,我很欣賞任何指導。

回答

2

簡答:沒有。對於批處理操作,Hibernate不會跟蹤生成的id,因此,您必須爲每個Name轉到數據庫,因爲您會根據名稱執行查詢,而不是基於ID,除非您使用一些查詢緩存(這對你的情況來說會很棘手,我想)。

我建議的是在兩步(三?)過程中做到這一點:首先,批量插入所有Name對象。然後,使用Hibernate自己加載它們,將它們存儲在Map上。然後,堅持其他數據,將Name鏈接到非持久性Person。當然,你需要儘可能多的內存,因爲你有名字:-)但爲什麼你保持Name作爲一個單獨的實體,無論如何?

+0

感謝您的回覆。是的,我想這種或那種方法我需要在每個實體的唯一約束的元組上鍵入一個映射,至少每個批次都有一個映射。我的意思是名稱是一個例證,在我的實際應用/模式/實體中,多對多關係更有意義。 – rhi