调用Oracle函数的JPA本机查询在同一事务上下文中的不同调用中返回相同的对象

氟帕酮

我在托管事务上下文中执行查询时遇到问题(使用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值的行时,将返回上一个实体。

根据您的提供商的不同,一些选项包括:

  1. 清除缓存。如果您正在事务中,则调用em.clear()可能会有所帮助,否则可能需要从共享缓存中逐出该实体。
  2. 强制刷新。EclipseLink有一个刷新查询提示,如果在第二个查询上使用它,将导致该实体重新加载第二组数据
  3. 不要将托管实体用于更适合原始数据的功能。如果您想要的只是数据的DTO,请使用此处概述的构造方法选项

选项3对我来说更有意义,因为破坏缓存和从其他查询返回的对象的风险较小。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在边界上下文中为同一事物适应不同的标识符

在 5 个 API 调用返回后触发一个函数(在分布式上下文中)

JPA:在同一事务中插入和删除对象

请解释“!”的含义 在函数调用的上下文中

在同一上下文中添加对象时,实体框架不会返回代理

不在对象上下文中时使用$ this在静态方法中调用简单方法

我如何一次调用API,以及如何在Vuejs的上下文中从同一API获取不同的内容

SPARK中不允许在干扰上下文中调用volatile函数

如何在Moose构造函数中确定在哪个上下文中调用它?

是否有可能在不同的上下文中调用具有相同签名的两个函数?(属性操作)

使用工作单元在同一事务中调用来自不同存储库的不同方法

从非静态上下文中调用同一类的Java构造函数会导致递归,但使用静态,它可以正常工作吗?

如何使用Spring JPA在同一事务中的不同数据库上维护多个sql查询

Java EE 7:从“非托管”上下文中调用EJB方法和事务

通过Spring Boot在同一上下文中创建的对象的两个不同的哈希码

检查上下文是否与意图调用中的类相同

Javascript:编写一个高阶函数以使用调用它的对象的上下文

SQL查询中函数调用的性能影响(关于上下文切换)

为什么要在C#中定义一个局部函数以立即调用它(在IEnumerable <T>的上下文中)

为不同的活动调用类中的上下文

EF Core:如何在不同的查询上下文中重用相同的表达式

如何在 API 函数调用上下文中从数据表中获取搜索行

如何在调用函数中设置空上下文?

JS:无上下文函数调用中的“ this”反弹

如何从上下文 API 中的组件调用函数?

在与GWT模块库不同的上下文中调用GWT服务?

为什么两个相同但连接不同的字符串在用python调用的shell上下文中具有不同的结果?

在错误抛出的上下文中,Oracle调用与执行之间的区别

将上下文中的实体替换为同一实体的不同实例