Sri*_*ala 13 java oracle pagination hibernate entitymanager
我正在尝试将分页与EntityManager.createNativeQuery(). 下面是我正在使用的骨架代码:
var query = em.createNativeQuery("select distinct id from ... group by ... having ...");
List<BigDecimal> results = query
.setMaxResults(pageSize)
.setFirstResult(pageNumber * pageSize)
.getResultList();
Run Code Online (Sandbox Code Playgroud)
当pageNumber是 0(第一页)时,我得到预期的 BigDecimals 列表:
但是一旦pageNumber> 0(例如,第二页),我就会得到一个对象列表,这个列表中的每个对象似乎都包含两个 BigDecimal,其中第一个包含来自数据库的值,第二个 BigDecimal 似乎是这一行的位置。
显然我得到了这个例外
java.lang.ClassCastException: 类 [Ljava.lang.Object; 不能强制转换为 java.math.BigDecimal 类
有人可以解释这种差异,以及如何修复它以始终返回 BigDecimals 列表?谢谢你。
更新 1:我创建了一个示例项目来重现此问题。我只能使用 Oracle 数据库重现此问题。使用 H2 数据库,它运行良好,并且我始终得到一个与页码无关的 BigDecimals 列表。
您遇到的问题是您的 OracleDialect 将一列添加到其选定的 ResultSet。它包装了您在 SternK 的回答中讨论的正在运行的查询。
如果您正在使用 Hibernate SessionFactory 和 Session 接口,那么您要寻找的函数将是“addScalar”方法。不幸的是,似乎没有纯 JPA 的实现(请参阅此处提出的问题:Does JPA has an equivalent to Hibernate SQLQuery.addScalar()?)。
我希望您当前的实现能够在 DB2、H2、HSQL、Postgres、MySQL(以及其他一些数据库引擎)中正常工作。但是,在 Oracle 中,它将行号列添加到 ResultSet,这意味着 Hibernate 从 ResultSet 中获取 2 列。在这种情况下,Hibernate 没有实现任何查询解析,这意味着它只是将 ResultSet 解析到您的 List 中。由于它获得 2 个值,因此它将它们转换为 Object[] 而不是 BigDecimal。
需要注意的是,依赖 JDBC 驱动程序提供预期数据类型有点危险,因为 Hibernate 会询问 JDBC 驱动程序它建议的数据类型。在这种情况下,它建议使用 BigDecimal,但在某些条件下和某些实现将被允许返回 Double 或其他一些类型。
那么你有几个选择。
您可以修改您的 oracle 方言(如 SternK 建议的那样)。这将利用替代的 oracle-paging 实现。
如果您不反对在 JPA 实现中使用特定于休眠的方面,那么您可以利用 JPA 标准中未提供的其他休眠功能。(见下面的代码...)
List<BigDecimal> results = entitymanager.createNativeQuery("select distinct id from ... group by ... having ...")
.unwrap(org.hibernate.query.NativeQuery.class)
.addScalar("id", BigDecimalType.INSTANCE)
.getResultList();
System.out.println(results);
Run Code Online (Sandbox Code Playgroud)
这确实具有显式告诉 hibernate 的优点,您只对 ResultSet 的“id”列感兴趣,并且 hibernate 需要将返回的对象显式转换为 BigDecimal,如果 JDBC 驱动程序决定不同的类型作为默认值会更合适。
经过对不同版本的不同 spring 库的大量尝试后,我终于能够解决这个问题。在我的一次尝试中,当我将 spring-data-commons 库从 v2.1.5.RELEASE 更新到 v2.1.6.RELEASE 后,这个问题似乎就消失了。我查了这个版本的changelog,这个bug与spring-data-commons中的这个bug相关,是这个问题的根本原因。升级 spring-data-commons 库后,我能够解决该问题。
| 归档时间: |
|
| 查看次数: |
2067 次 |
| 最近记录: |