H2 查询失败,“节点没有数据类型:org.hibernate.hql.internal.ast.tree.MethodNode”
Posted
技术标签:
【中文标题】H2 查询失败,“节点没有数据类型:org.hibernate.hql.internal.ast.tree.MethodNode”【英文标题】:H2 query failing with 'No data type for node: 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 数据库。
【参考方案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不支持函数的使用。我找不到任何支持相同的文档,但我想我会把它留在这里作为一个选项,以防其他人面临这个问题。
【讨论】:
以上是关于H2 查询失败,“节点没有数据类型:org.hibernate.hql.internal.ast.tree.MethodNode”的主要内容,如果未能解决你的问题,请参考以下文章
Mysql SQL查询DATEDIFF在H2中失败,其中模式是MYSQL