我面對類似於Invalidating JPA EntityManager session描述的一個問題:使用JPA時避免來自數據庫的陳舊數據?
問題:讓舊數據
我們正在運行JPQL的查詢也同時由不同的應用程序更改SQL數據庫上。我們使用在Tomcat下運行的JSF + Spring + EclipseLink。
類做JPQL查詢是一個單獨的Spring bean,並使用注射EntityManager
:
@Component
public class DataRepository{
@PersistenceContext
private EntityManager entityManager;
public List<MyDTO> getStuff(long id) {
String jpqlQuery ="SELECT new MyDTO([...])";
TypedQuery<MyDTO> query = entityManager.createQuery(jpqlQuery,MyDTO.class);
return query.getResultList();
}
[...]
(代碼轉述)。
問題是此代碼沒有看到直接在數據庫上執行的更改。如果Tomcat實例重新啓動,這些更改只會變得可見。
我們已經嘗試
我們假設該行爲是由相關的EntityManager
一級高速緩存中引起的,如鏈接的問題進行說明。我們發現了兩個解決方案:
- 呼叫
entityManager.clear()
調用createQuery
之前(這是建議的鏈接的問題) - 注入的
EntityManagerFactor
(使用@PersistenceUnit
),然後創建並關閉新EntityManager
爲每個查詢
這兩種解決方案都能做到我們想要的 - 我們獲得新的數據。
問題:
- 是這兩種解決方案是否正確?哪一個更好?
- 特別是,我們可以安全地在注入的EntityManager上調用
entityManager.clear()
,或者這會以某種方式影響也使用注入的EntityManager的其他代碼(在相同或不同的類中)? - 有沒有不同的更好的方法?我們可以以某種方式聲明我們想刷新緩存,或者我們想要一個新的
EntityManager
?
我想這一定是一個相當普遍的問題(因爲它發生時多個應用程序共享一個數據庫),所以我想必須有一個簡單的解決方案...
我認爲這不是很常見的共享與多個應用程序的數據庫?這聽起來像你會不斷重新加載你的EntityManager而受到嚴重懲罰。你不能通過服務提供所需的數據嗎?或者在應用程序之間使用一些共享緩存? – vertti
@vertti:好點。我沒有意識到JPA在使用共享數據庫時存在這樣的問題。當然,使用服務或類似服務是可能的,但這意味着一個重大變化,而且不太可能發生。 – sleske