【问题标题】:H2 query failing with 'No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode'H2 查询失败,“节点没有数据类型:org.hibernate.hql.internal.ast.tree.MethodNode”
【发布时间】:2016-10-27 18:10:37
【问题描述】:

我有一个自定义查询,它适用于 postgres,但在 H2 中失败。

select distinct(to_char(date_requested,'YYYY')) 
from Product 
where date_requested is not null

我得到的例外是:

> Caused by: java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode 
     \-[METHOD_CALL] MethodNode: '('
        +-[METHOD_NAME] IdentNode: 'to_char' {originalText=to_char}
        \-[EXPR_LIST] SqlNode: 'exprList'
           +-[IDENT] IdentNode: 'date_requested' {originalText=date_requested}
           \-[QUOTED_STRING] LiteralNode: ''YYYY''

我的另一个查询,与 to_char 的用法类似,效果很好:

select count(*), requester 
from Product 
where to_char(date_requested,'YYYY') = '2016' 
group by requester 
ORDER BY Count(*) desc

我确实有最新版本的 H2,1.4.192,所以我知道 to_char 的使用是可以的。

我在这里做错了什么?为什么第一个查询不适用于 H2?

【问题讨论】:

  • 不相关,但是:distinct 不是函数。将表达式放在括号之间不会改变任何不同的东西。 distinct (a) 与 distinct a 相同
  • 是的,我知道这一点。这是我正在为其编写单元测试的同事的查询。无论如何,是的,无关。感谢您的编辑。
  • 在没有混淆层(又名 ORM)的情况下运行查询是否有效
  • 不幸的是,我无法检查这个。我的 DBMS 使用的是不支持 to_char 的旧版 H2 驱动程序。将其更改为使用最新的 H2 驱动程序 jar(取自 link,当我尝试连接时出现错误 java.lang.UnsupportedClassVersionError: org/h2/Driver : Unsupported major.minor version 51.0到 H2 数据库。

标签: hibernate h2


【解决方案1】:

我遇到了同样的问题。

通过使用最新版本的 H2,这些 TO_DATE、TRUNC、TO_CHAR 函数在 H2 中呈现。

这里的问题是你使用hibernate作为ORM后端,而普通的H2Dialect不理解这些功能。您可以将此方言子类化以映射新功能。例如,这是我用于 TRUNC 函数的那个​​。

package my.awesome.project;

import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StandardBasicTypes;

public class CustomH2Dialect extends H2Dialect {

    public CustomH2Dialect() {
        super();
        registerFunction("trunc", new StandardSQLFunction("trunc", StandardBasicTypes.TIMESTAMP));
    }
}

然后您将休眠设置“connection.driver_class”替换为:

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">

  <persistence-unit name="thePersistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="connection.driver_class" value="org.h2.Driver"/>
        <property name="hibernate.connection.url" value="jdbc:h2:./db/repository"/>
        <property name="hibernate.dialect" value="my.awesome.project.CustomH2Dialect"/>
        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        <property name="hibernate.show_sql" value="true" />

    </properties>
  </persistence-unit>

【讨论】:

    【解决方案2】:

    因此,当我从所有查询中删除 to_char 函数时,问题就消失了。有同事告诉我H2不支持函数的使用。我找不到任何支持相同的文档,但我想我会把它留在这里作为一个选项,以防其他人面临这个问题。

    【讨论】:

      猜你喜欢
      • 2018-07-20
      • 2021-09-23
      • 1970-01-01
      • 2015-08-16
      • 2014-12-15
      • 1970-01-01
      • 2016-09-19
      • 2022-01-19
      相关资源
      最近更新 更多