gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 16:52:38 25 4
gpt4 key购买 nike

我在托管事务上下文中执行查询时遇到问题(使用 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 对象引用与第一个对象的引用相同),尽管调用它的参数不同.

这似乎是一个缓存问题;所以我明确地将以下属性添加到我的 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. 清除缓存。如果您处于交易,否则您可能需要将该实体从共享缓存。
  2. 强制刷新。 EclipseLink 有一个刷新查询提示如果在第二个查询中使用,将导致实体成为重新加载第二组数据
  3. 不使用托管实体对于更适合原始数据的功能。如果你想要的一切是数据的 DTO,使用概述的构造函数选项 here

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

关于sql - 调用 Oracle 函数的 JPA native 查询在同一事务上下文中的不同调用中返回相同的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35990438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com