HQL 调用封闭函数时没有节点异常的数据类型

Posted

技术标签:

【中文标题】HQL 调用封闭函数时没有节点异常的数据类型【英文标题】:HQL No data type for node exception when calling enclosed functions 【发布时间】:2016-02-01 07:05:04 【问题描述】:

当我打电话时

List<Object[]> list = session.createQuery("select n.book, nvl(sum(n.val),0) from N n).list();

Hibernate 在解析查询时遇到一些问题并抛出:

java.lang.Exception: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode 
 \-[METHOD_CALL] MethodNode: '('
    +-[METHOD_NAME] IdentNode: 'nvl' originalText=nvl
    \-[EXPR_LIST] SqlNode: 'exprList'
       +-[AGGREGATE] AggregateNode: 'sum'
       |  \-[DOT] DotNode: 'n0_.val' propertyName=val,dereferenceType=PRIMITIVE,getPropertyPath=val,path=n.val,tableAlias=n0_,className=com.myCompany.name.entity.account.N,classAlias=n
       |     +-[ALIAS_REF] IdentNode: 'n0_.id' alias=n, className=com.myCompany.name.entity.account.N, tableAlias=n0_
       |     \-[IDENT] IdentNode: 'val' originalText=val
       \-[NUM_INT] LiteralNode: '0'

然而

List<Object[]> list = session.createQuery("select n.book, sum(n.val) from N n).list();

工作正常。 我想知道我的第一个查询语法是否有问题或 Hibernate 不知何故不支持封闭函数?

编辑:NVL 是 Oracle 功能,我们在生产中使用 Oracle DB。但是我使用内存中的 H2 数据库进行单元测试。 H2 is said to support NVL as well.

【问题讨论】:

【参考方案1】:

您似乎对 SQL 和 HQL 有点困惑。 HQL 不是 SQL。 SQL 支持很多功能,但它们是特定于实现的。其中一些是“标准的”,即在不同的数据库中具有相似的实现。

HQL 提供独立于平台的方式来从关系数据库中查询对象,并且仅支持非常有限的函数列表(summinmaxavgcount)。详情请看以下资源:https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-aggregation

尝试谷歌“sql nvl function”并查看结果。 Oracle 支持此功能,但 mysql 不支持此功能(例如)。这意味着它很难让hibernate支持它。此外,特别是对于这个功能,恕我直言,即使尝试使用它也不是一个好方法。将用其他值替换 nulls 的责任转移到您的实体或 DAO 层。

【讨论】:

感谢您的回复。我想我应该澄清我的问题。现在,我正在使用上述查询测试代码,该查询与生产中的 Oracle DB 一起使用。出于测试目的,我使用了支持 nvl 的内存 H2 DB。 我明白了。我认为你的数据库支持某些操作是不够的。您需要对 Hibernate 实现的相应方言的适当支持。可能 H2 的方言不支持此功能。但同样,你走错路了。尝试找到允许尽可能简化查询并将逻辑移动到 Java 代码的设计。这将帮助您使代码更具可测试性、稳定性和可移植性。

以上是关于HQL 调用封闭函数时没有节点异常的数据类型的主要内容,如果未能解决你的问题,请参考以下文章

hibernate hsql得到错误节点没有数据类型:org.hibernate.hql.ast.tree.IdentNode

HTTP 状态 500 - 节点没有数据类型:org.hibernate.hql.internal.ast.tree.IdentNode

H2 查询失败,“节点没有数据类型:org.hibernate.hql.internal.ast.tree.MethodNode”

原因:org.hibernate.QueryException:节点没有数据类型:org.hibernate.hql.internal.ast.tree.MethodNode

实体类和数据表的映射异常(XXX is not mapping[ ])

重构时无法提取对封闭类方法的引用