简体   繁体   中英

HQL No data type for node exception when calling enclosed functions

When I call

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

Hibernate has some trouble parsing the query and throws:

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'

However

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

works fine. I wonder if something is wrong with my 1st query syntax or Hibernate somehow doesn't support enclosed functions?

EDIT: NVL is Oracle function and we use Oracle DB in production. However I use in-memory H2 database for unit-testing. H2 is said to support NVL as well .

It seems that your are a little bit confused with SQL and HQL. HQL is not SQL. SQL supports a lot of functions but they are implementation specific. Some of them are "standard", ie have similar implementation in different databases.

HQL provides platform independent way to query objects from relational database and supports only very limited list of functions ( sum , min , max , avg , count ). Please see the following resource for details: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-aggregation

Try to google "sql nvl function" and see the results. This function is supported by Oracle but not supported by MySQL (for example). This means that its very difficult to make hibernate to support it. Moreover specifically to this function it IMHO it is not a good way even to try to use it. Move responsibility on replacing null s by other values to your entity or to your DAO layer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM