我在托管事务上下文中执行查询时遇到问题(使用JTA事务工厂)
在整个请求执行期间,查询应执行两次:第一次从数据库中获取默认值;第二次从数据库中获取默认值。第二次,使用不同的参数运行时,它应该返回具有不同值的不同对象。
查询本身对Oracle数据库中的函数进行调用,如下所示:
SELECT attr1, attr2, attr3
FROM TABLE(package.function (
param1 => :param1,
param2 => :param2,
param3 => :param3))
执行查询的方法(必须使用不同的参数执行两次)类似于:
public MyEntity getMyEntity(Map<String,String> params) {
String sql = getQuery(); // gets the string of the aforementioned query
Query query = getEntityManager().createNativeQuery(sql, MyEntity.class);
query.setParameter("param1", params.get("param1"));
query.setParameter("param2", params.get("param2"));
query.setParameter("param3", params.get("param3"));
return (MyEntity) query.getSingleResult();
}
问题在于,在执行请求期间,第一次调用此方法时,它将返回一个MyEntity
正确的特定对象。但是,第二次调用该函数时,该函数getMyEntity
错误地返回了完全相同的对象(他的Java Object引用与第一个对象的引用相同),尽管调用该函数的参数不同。
似乎是一个缓存问题;所以我persistence.xml
将以下属性明确添加到我的文件中
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.SingletonEhCacheProvider"/>
<property name="hibernate.cache.use_second_level_cache" value="false"/>
<property name="hibernate.cache.use_query_cache" value="false"/>
并设置查询提示
query.setHint(QueryHints.CACHEABLE, false);
但是问题仍然存在。
我想问一下我是否缺少什么,是否有解决此问题的方法。
注意:该代码是项目的一部分,该项目是将旧应用程序移植到基于RESTful Apis的新版本上的,因此更改代码的逻辑结构不是一个选择。
JPA规范要求
getEntityManager().createNativeQuery(sql, MyEntity.class);
返回MyEntity的托管实例。您正在管理由第一个查询生成的MyEntity实例,并跟踪其更改,当然,其身份也将得到管理。加载实体后,每次查询该实例都会返回该实例。因此,当您的下一个查询返回具有相似ID值的行时,将返回上一个实体。
根据您的提供商的不同,一些选项包括:
选项3对我来说更有意义,因为破坏缓存和从其他查询返回的对象的风险较小。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句