2016-09-07 62 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