在JPA中禁用caching(eclipselink)

我想使用JPA(eclipselink)从我的数据库中获取数据。 数据库被其他许多来源所改变,因此我想回到执行的每个查找的数据库。 我已经阅读了许多关于禁用caching的post,但这似乎并没有工作。 有任何想法吗?

我试图执行下面的代码:

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("default"); EntityManager em = entityManagerFactory.createEntityManager(); MyLocation one = em.createNamedQuery("MyLocation.findMyLoc").getResultList().get(0); MyLocation two = em.createNamedQuery("MyLocation.findMyLoc").getResultList().get(0); System.out.println(one==two); 

一个==两个是真的,而我希望它是假的。

我已经尝试添加每个/所有以下到我的persistence.xml

 <property name="eclipselink.cache.shared.default" value="false"/> <property name="eclipselink.cache.size.default" value="0"/> <property name="eclipselink.cache.type.default" value="None"/> 

我也尝试添加@Cache注释到实体本身:

 @Cache( type=CacheType.NONE, // Cache nothing expiry=0, alwaysRefresh=true ) 

我误解了什么?

这种行为是正确的,否则如果你改变对象一和对象二不同的值,你将会遇到问题时,坚持他们。 发生什么事是调用加载对象两个更新在第一次调用加载的实体。 他们必须指向同一个对象,因为他们是同一个对象。 这确保了不能写入脏数据。

如果你在两个调用之间调用em.clear(),实体之一应该分离,你的检查将返回false。 然而,没有必要这样做,日食链接实际上更新您的数据到最新的,我猜是你想要的,因为它经常改变。

在附注中,如果您希望使用JPA来更新这些数据,您将需要获得对实体的悲观locking ,以便底层数据无法在数据库中更改。

你将需要禁用查询caching以及你的caching选项只是从播放中删除对象caching而不是查询caching,这就是为什么你没有得到新的结果:

在你的代码中:

 em.createNamedQuery("MyLocation.findMyLoc").setHint(QueryHints.CACHE_USAGE, CacheUsage.DoNotCheckCache).getResultList().get(0); 

或者在persistence.xml中:

 <property name="eclipselink.query-results-cache" value="false"/> 
 final Query readQuery = this.entityManager.createQuery(selectQuery); readQuery.setParameter(paramA, valueA); // Update the JPA session cache with objects that the query returns. // Hence the entity objects in the returned collection always updated. readQuery.setHint(QueryHints.REFRESH, HintValues.TRUE); entityList = readQuery.getResultList(); 

这对我有用。

看到,

http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching

对于同一个EntityManager,JPA总是要求一个==两个,所以这是正确的,不pipe你的caching选项(这是L1caching,还是事务caching,它强制你的事务隔离和维护对象的身份)。

要强制查询刷新(并恢复所做的任何更改),可以使用查询提示“eclipselink.refresh”=“true”。 或者可能更好,为每个查询/请求使用一个新的EntityManager,或在您的EntityManager上调用clear()。

 <property name="eclipselink.cache.shared.default" value="false"/> 

禁用共享caching(L2caching)是正确的方法。 请删除所有其他设置,因为它们不正确,可能会导致问题。

EclipseLink默认情况下不会保留查询caching,所以这些设置不会有任何影响。 CacheUsage也是不正确的,不要使用这个(它用于内存查询)。

如果您希望禁用caching而无需获取供应商特定的信息,则可以使用以下注释来注释域对象:

 @Cacheable(false) 

这里是一个例子:

 @Entity @Table(name="SomeEntity") @Cacheable(false) public class SomeEntity { // ... } 

如果手动修改对象的属性,例如MyLocation。 上面的技巧( CACHE_USAGE=CacheUsage.DoNotCheckCache ,或CACHE_USAGE=CacheUsage.DoNotCheckCache eclipselink.query-results-cache=false )似乎不工作,因为我试过。

所以我试图设置eclipselink.refresh另一个提示为true 。 那么它的工作。 我的意思是手动更改的属性被检索。

所以,据我了解,上述技巧只能确保它得到正确的对象。 但是,如果对象已经被caching了,eclipselink只是返回它们而不检查对象内容的新鲜度。 只有当提示eclipselink.refresh设置为true ,这些对象才会刷新以反映最新的属性值。

我知道这个post可能很老,但是我正在为需要帮助的人写信。 我有这个问题,最后我解决了这个代码:

 em.createNamedQuery("findAll").setHint(QueryHints.CACHE_RETRIEVE_MODE, CacheRetrieveMode.BYPASS).getResultList(); 

它工作得很好。 我们可以在BYPASS枚举的javadoc中看到,它写道:

绕过caching:直接从数据库中获取数据。

我应该注意到,我使用Weblogic 12c和TopLink作为JPA实现。