2016-09-07 74 views
0

我有兩個存儲過程調用返回User實體。通過包含在用戶實體中的兩個參數而不是來查看用戶是否註冊。如果該過程沒有返回任何用戶,則會調用第二個存儲過程來註冊該用戶。Eclipselink爲存儲過程禁用緩存

我看到的行爲是,當按此順序調用時,第二個存儲過程從緩存中返回一個User實體,該實體幾乎包含所有字段爲空的緩存。當我禁用緩存時,它會適當地返回用戶對象。看起來第一個調用是緩存用戶對象。

在用戶登錄的正常操作中,我希望它緩存,所以我不想在第一次調用時禁用緩存。我想第二次存儲過程調用不使用緩存。在做了一些研究和測試一些選項後,我發現了幾個選項。

這不會對存儲過程的工作:

proc.setHint("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS); 

java.lang.IllegalArgumentException: Query linkUser, query hint javax.persistence.cache.retrieveMode is not valid for this type of query. 

這看起來像驅逐所有所有用戶的緩存。

em.getEntityManagerFactory().getCache().evict(User.class); 

而且these選項無論是實體的還是整個應用程序的所有實例禁用緩存。

  1. 如何使用Eclipselink對單個存儲過程調用不使用緩存?

  2. 獎勵:爲什麼要緩存返回空用戶的存儲過程調用?

回答

0

找到一個Java EE Tutorial,它顯示瞭如何逐出個人緩存。我仍然不確定爲什麼它被緩存,因爲第一次調用從來沒有userId。

Cache cache = em.getEntityManagerFactory().getCache(); 
cache.evict(User.class, userId); 
1

JPA規範要求所有的實體從JPA查詢返回的(包括本地和存儲過程中查詢)進行管理,這意味着他們也緩存到維護對象的身份。如果你的第一個查詢返回一個不完整的實體,這也將被緩存。應用程序在使用查詢返回一組完整數據的實體時需要小心,或者它們可能會破壞緩存,並且還要注意,它們的實體可能從緩存中被取出,而不是使用查詢中的數據重建,並且可能會想要返回java對象(構造函數查詢)而不是JPA實體。

爲了回答第一部分,見https://stackoverflow.com/a/4471109/496099

+0

第一個SP調用不會返回部分的實體,則返回null。這兩個查詢參數甚至不是實體的一部分。我現在試圖弄清楚緩存中的任何事情,以及爲什麼在調用之前移除緩存的實體可以解決問題。 – blur0224