2012-05-09 40 views
1

我有一些簡單的簡單實體bean(EJB 3.1,Glassfish,EclipseLink)的應用內緩存,所以我不必在數據庫中查找它們每次應用程序需要快速時都會發現findById。這些實體bean是隻讀的。JPA分離的實體作爲合併期間的管理實體的一部分

因此,例如實體bean Country或Currency在本地緩存中。

發生在Java EE應用程序中的一些進程希望更新複雜的實體bean(即Customer),該實體bean使用上面的簡單Bean(Country,Currency ...)。

然後會發生什麼是因爲簡單的實體bean與JPA上下文的連接丟失,當在Customer bean上嘗試.merge()時,JPA希望將簡單的實體bean作爲新記錄保存在數據庫中,儘管這些數據庫已經存在100%,所以我想這是一個「分離的實體」問題。

例子。

Country country = getFromCacheByName("GB"); // detached entity, but exists in database 
Customer customer = getCustomerFromJPA(); // existing JPA attached entity 
customer.setCountry(country); 
EntityManager.merge(customer); // pseudo code 

如何解決最後一行,或豆(客戶)本身,因此它不會試圖挽救依賴對象(國家)對.merge()?

謝謝。

+0

就像一條評論,我試圖在從緩存中檢索到.merge(國家)後,它並沒有真正起作用,JPA仍然試圖將簡單的bean作爲事務的一部分持久化(上面的代碼的最後一行)。無論如何,我不需要這些簡單的bean合併,我只是希望它們不會因爲它們已經存在而被作爲數據庫中的新記錄持久化。 – bozo

+0

與原始問題無關,是否考慮將外鍵用於'Country'而不是將其設置在Customer中,然後合併。我認爲在創建客戶之前你會有國家對象。 –

+0

嗨Nayan,我不太瞭解你的建議。謹慎闡述? – bozo

回答

1

在設置到客戶之前,您應該在該國家進行find()或merge()。另外,確保它有正確的ID。

合併客戶也應該工作,但它會試圖插入國家,如果它的ID是存在的,這很奇怪,但這可能取決於您如何配置事物。你在國家關係上合併了嗎?

請注意,EclipseLink有它自己的緩存。所以你的應用程序緩存可能不需要。

+0

我試着做EntityManager.merge(國家) - 它沒有幫助。一般關於EclipseLink緩存和JPA緩存。我有許多地方的代碼,如daoSomething.findByName(「a」),它返回簡單的實體(即貨幣)。每次它進入數據庫並做SELECT ... FROM貨幣WHERE ID = ...就好像根本沒有緩存一樣。任何想法如何在EclipseLink中激活緩存?我談論的是一些簡單的事情,比如通過ID或者一列獲取簡單的實體。 – bozo

+0

「你是否在級聯國家關係合併」 - 關於這一點,我沒有關於任何關係設置CascadeType,所以它應該是默認的。所以客戶只需擁有一個簡單的屬性@ManyToOne國家/地區;並沒有更多的註釋。 – bozo

+0

這是我的不好。實際上父對象的merge()確實起作用,我使用的代碼稍微複雜一些,而.merge()根本就沒有被調用。謝謝你的回答。 – bozo