2013-11-23 31 views
1

我正在考慮在應用程序中使用JPA以保留多個對象。使用JPA手動控制數據庫更新

應用程序的使用似乎不符合標準的JPA辦法同意,雖然在每一個變化的對象更新。

應用的使用將使得只有幾百對象將是活動的時間,但這些每個人都可以每秒數次更新。

當應用程序在內存中的對象,沒有必要讓他們在數據庫中不斷更新,這純粹是無用的IO。

是否有可能使用JPA加載在會話中的幾個對象,並在不影響其他實體管理的對象,對其進行更改內存幾分鐘,然後更新數據庫?

如果有辦法與一些對象的會話之間共享這樣做這將是最有幫助的。

回答

1

如果您希望沒有對您的實體進行數據庫更改,只需將它們從實體管理器中分離出來即可。

  1. 要在事務處理期間從實體管理器中分離對象,只需使用detach方法。
  2. 如果實體未被管理(即在交易關閉後),那麼該實體無論如何不被管理,並且您可以在沒有額外代碼的情況下對其進行更改。

從JPA 2.0規範的摘錄,在一個實體如何被分離:如果使用 事務範圍的容器管理的實體管理

甲分離從事務實體的結果提交(見 第3.3節);從事務回滾(參見3.3.2節); from 從持久性上下文中分離實體;從清除 持久性上下文;從關閉一個實體經理;或者從 序列化的實體或以其他方式價值 - 例如通過一個實體,以 單獨applica-重刑層,通過遠程接口等

然後當決定讓你的數據庫的更改,只需合併分離的實體:entityManager.merge(entity);

我想是什麼,你錯過了一些JPA背景,例如一個實體的狀態是什麼,一個entityManager的操作是什麼。我建議您搜索一些教程,或閱讀JPA spec中的一些章節(閱讀第3.2章實體實例的生命週期 ,大約5頁,我保證您會理解很多)。此外,如果您希望MERGE操作級聯,那麼JPA中也有解決方案。 對於EntityManager上的操作&在JPA中有很好的介紹:the official tutorial

UPDATE 我會盡力形容你在這些教程中很重要的一點。

實體實例(即,如果它與Persistence Context(〜EntityManager)相關聯,則它是管理的。如果它被管理,則跟蹤它的更改,這意味着更改託管實體實例將同步到數據庫。這些改變與數據庫同步,例如,當交易完成或當您致電entityManager.flush()(請閱讀子章節3.2.4與數據庫同步以獲取更多詳細信息)。

合併操作實際上是您用來更新和保留實體實例E1的操作。它返回一個被管實體實例E2,而傳遞的實體E1不被管理。

一個分離的另一邊實體不被entityManager跟蹤,即EntityManager的不會看到你所做的更改,直到你不合並的實體。

這兩種操作(還有一個持久性操作,我沒有討論過)是您切換管理的實體實例狀態 - >分離的方式。

現在與您有關根的問題&子女:如果沒有配置任何內容,則在您的根上調用merge()detach()不會影響您的孩子。但是,您可以在JPA中使用級聯方案,例如調用entityManager.merge(root),也會對其子級調用。當然,由您來決定哪個操作是級聯的,哪個不是。

+0

我確實想要更改數據庫,我只想控制它什麼時候發生,什麼對象。 –

+1

更新了我的答案。您只需將實體在分離和管理狀態之間移動即可。 –

+0

謝謝!最後一個小問題: 合併和分離的範圍是什麼? 假設我有一些「根對象」與OneToOne或OneToMany關係到一些其他對象,這些對象可以在根對象之間共享。 當我調用分離和合並根對象時會發生什麼? 我是否已經調用了僅用於根對象或所有子對象的方法? –

1

您可以通過創建自己的實體管理器來控制實體的預期壽命。

不清楚您是在談論JEE還是獨立應用程序,但無論如何,您都需要訪問實體管理器工廠,並從中獲取實體管理器。

您的實體管理器將鏈接到持久性上下文。每次你要求一個實體時,它都會被放置在這個持久化上下文中。如果您讓實體經理保持開放狀態,那麼只有您第一次閱讀實體時纔會觸及數據庫。而下一次,你將從這個緩存中獲得它們。

如果您使用資源本地事務,則可以控制何時將更改刷新到數據庫。如此一來,您可以在一段時間內更改您的上下文,然後決定通過提交事務或通過調用flush方法來刷新它。

您可能想要閱讀this another answer以獲得對持久性上下文以及它們如何工作的更多理解。

- 編輯 -

有多種方式取決於應用程序,你正在構建的類型,以獲得您的實體管理器工廠的訪問。

如果這是一個獨立的應用程序,你可以的,如果你使用的是依賴注入框架做

EntityManagerFactory emf = Persistence.createEntityManagerFactory("unit-name"); 

,那麼你可以用它來自動注入它。如果您在JEE應用程序中,您可以使用它自動注入爲您使用

@PersistenceUnit(unitName="main") 
private EntityManagerFactory emf; 
+0

當你說創建,你的意思是實現或實例化? 我的意思是,我是否必須創建自己的entitymanager類,或者只是簡單地掌握entitymanager工廠並實例化我自己的類? –

+1

@MartinNielsen我編輯了我的答案給你更多的細節。 –

+0

我已經1up了,謝謝:) –