getSingleResult 在休眠中返回本地标量查询的代理

Posted

技术标签:

【中文标题】getSingleResult 在休眠中返回本地标量查询的代理【英文标题】:getSingleResult returns proxy on native scalar query in hibernate 【发布时间】:2012-01-12 21:03:06 【问题描述】:

我正在将我的 JPA 持久性提供程序从 EclipseLink 2.3 切换到 Hibernate 3.6.5.Final。问题在于本机查询。注意:这不是 EclipseLink 的问题。我正在尝试从没有声明实体的表中获取标量值 String。代码如下:

Query q = em.createNativeQuery("select description from foo where foo_id = ?");
q.setParameter(1, fooId);
String description = (String)q.getSingleResult();

使用 Hibernate,我得到一个 ClassCastException,因为返回的对象实际上是一个代理对象。我不知道它是什么类型,但我知道它不是一个数组(object.getClass().isArray() 是假的)而且我知道它不是一个列表(object instanceof Listfalse)。

我错过了什么?

【问题讨论】:

q.getSingleResult().getClass().getInterfaces()返回什么接口? 啊……这正是我所需要的。它的类型为 java.sql.Clob、org.hibernate.engine.jdbc.WrappedClob 和 java.io.Serializable。如果你做出这样的回答,我会接受。我什至没有意识到该列是一个 clob,我很惊讶 EclipseLink 正在为我转换为 String。 仅供参考,在转换为 Hibernate 时还有另外两个问题。 (1) 在 EntityY 上调用 getEntityXList() 方法以强制 EntityManager 查询数据库并加载在 EclipseLink 中工作的延迟加载列表,但我必须让它 getEntityXList().size() 才能在 Hibernate 中工作。 (2) 无类型的条件查询在 EclipseLink 中有效,但在 Hibernate 中我得到一个关于没有选择的异常。我刚刚添加了类型: CriteriaQuery cq = builder.createQuery(EntityX.class); 为我工作! ***.com/questions/28993398/… 【参考方案1】:

总结问题下方的cmets:

q.getSingleResult().getClass().getInterfaces() 返回什么接口?


它的类型为java.sql.Cloborg.hibernate.engine.jdbc.WrappedClobjava.io.Serializable。 [...] 我什至没有意识到该列是一个 clob,我很惊讶 EclipseLink 正在为我转换为字符串


看起来 EclipseLink 足够聪明,可以在需要时将 CLOB(实际上是一个很长的字符序列,就像 String)转换为 String。对于 Hibernate,这必须明确地完成。我猜这符合 JPA 规范。

【讨论】:

【参考方案2】:

您是否为休眠配置了正确的数据库方言?方言用于映射标量值的类型。

【讨论】:

我正在使用 Oracle 数据库,并且已在我的应用程序服务器的 DataSource 中对其进行了配置。当 Hibernate 初始化它时,它会在日志中报告 - 使用方言:org.hibernate.dialect.Oracle10gDialect 所以我猜它想通了。

以上是关于getSingleResult 在休眠中返回本地标量查询的代理的主要内容,如果未能解决你的问题,请参考以下文章

JPA getSingleResult() 或 null

getSingleResult 和 selectone

在 getSingleResult 聚合中处理 null 的正确方法

getSingleResult() 改变 count() 查询

JPA 中的 getSingleResult() 抛出异常

SKProduct 中的本地化标题为零