2012-01-08 97 views
3

我想了解JPA如何工作。據我所知,如果你堅持一個實體,那個對象將留在內存中直到應用程序關閉。這意味着,當我查找先前持久化的實體時,將不會對數據庫進行查詢。假設沒有進行插入,更新或刪除操作,如果應用程序運行的時間足夠長,則其中的所有信息可能會持續存在。這是否意味着在某些時候,我將不再需要數據庫?實體持續多久?

編輯

我的問題是不是與數據庫。我確信數據庫不能從應用程序外部修改。我自己管理事務,所以一旦我提交,數據就會存儲在數據庫中。我的問題是:在我提交後,實體會發生什麼?它們是否保存在內存中並像緩存一樣?如果是這樣,他們在那裏呆多久?在我提交persist後,我做了一個select查詢。這個選擇應該返回我之前堅持的對象。該對象是從內存中獲取的,還是應用程序將查詢數據庫?

回答

3

JPA無法只使用持久性上下文(L1緩存)或顯式緩存(L2緩存)。它總是需要與一個數據源相結合,並且這個數據源通常指向一個堅持穩定存儲的數據庫。

因此,只要事務(這是JPA持久操作所需的)未提交,實體就在內存中。之後,它被髮送到數據源。

如果事務管理器是事務範圍('正常'的情況),那麼L1高速緩存(持久化上下文)關閉,實體不再存在。如果L1緩存以某種方式困擾着你,你可以明確地管理它。有一些操作可以清除它,並且可以將寫入操作中的讀取操作(不需要事務)分開。如果讀取時沒有事務處於活動狀態,則不存在持久化上下文,實體將永遠不會連接,因此不會放入此L1緩存。

但是,當事務提交併且其中的實體仍然可用於整個應用程序時,L2緩存不會被清除。此L2緩存必須明確配置,並且作爲應用程序開發人員必須指出應在其中緩存哪些實體。通過供應商特定的機制(例如JBoss Cache,Infinispan),您可以對正在緩存的實體數量設置最大值,並設置/定義所謂的逐出策略。

當然,沒有什麼能夠阻止你讓數據源指向內存中的嵌入式數據庫,但這是JPA的知識。

+0

我不是故意刪除數據庫。我試圖瞭解是否在提交之後,所有這些實體將保留在內存中,並像緩存一樣。我經常需要一些信息。這就是爲什麼我不想每次都查詢數據庫的原因。列表會在應用程序本身中創建冗餘嗎? – Dragos 2012-01-08 17:38:51

+1

如果您不想每次都進行查詢,則可以配置L2緩存以及可選的查詢緩存。在極少數情況下,您還可以選擇利用擴展持久化上下文,該上下文會將L1緩存在應用指定的持續時間內保持打開狀態,但這很棘手,因此首先嚐試L2;) – 2012-01-08 17:44:08

5

不是。想想看。

您的應用程序可能不是唯一會使用數據庫的東西。如果一個實體被堅持一次並存儲在內存中,那麼您如何確信,一小時後,它不會被其他方式改變?如果發生這種情況,您將擁有可能會損害應用程序邏輯的陳舊數據。

將數據存儲在內存中,並希望一切都會好起來不會帶來任何好處。這就是爲什麼存儲在數據庫中的數據是您的主要信息來源,並且您應該每次都查詢它,除非您確定一部分數據不會更改。

+0

請看我編輯的內容。 – Dragos 2012-01-08 17:31:08

3

持久意味着短期內:您可以關閉您的應用程序,並且數據不會丟失。

爲了達到這一目的,您需要一個數據庫或某種保存數據的方式,以便在關閉應用程序時不會丟失數據。

4

當你堅持一個實體一個實體時,它會將它添加到作爲第一級緩存(這是在內存中)的持久性上下文中。何時發生實際持續取決於您是使用容器管理的事務還是自己處理事務。只要事務沒有被提交,實體實例就會存在於內存中,並且它會保存到數據庫或XML等。

+1

因此,在事務之後,所有對象都會被刪除,並且只有數據庫中的數據仍然存在? – Dragos 2012-01-08 17:32:05

+2

是的,這幾乎是正確的。但是,如果您仍然獲得了對entitymanager持續存在的實體對象的引用,您仍然可以在內存中使用它。但是,當事務結束時,狀態的進一步同步將不會反映在數據庫中。 – Andreas 2012-01-08 19:56:30

3

要「堅持」,實體意味着將其實際保存在數據庫中。當然,JPA在持久化上下文中維護一些實體信息(這在很大程度上取決於配置和編程實踐),但是在某些時候,信息將存儲在數據庫中 - 例如,當事務提交或可能但不一定)在flush()merge()操作後。

3

如果您希望在提交後保留實體併爲選擇查詢保留實體,則需要使用查詢緩存。只是谷歌周圍的這個詞,它應該是清楚的。