【发布时间】:2014-04-20 04:06:41
【问题描述】:
我有一个数据表,其中包含 setup 和 release 列,两者都包含时间戳。我的目标是使用 CriteriaQuery 创建下面的 SQL 查询的等效项。
SQL查询:SELECT TIMESTAMPDIFF(SECOND, setup, released)) as sum_duration FROM calls
CriteriaBuilder#diff() 函数显然不起作用,因为它需要数字参数,所以我尝试使用 CriteriaBuilder#function:
EntityManager entityManager = emProvider.get();
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Integer> query = criteriaBuilder.createQuery();
Root<Thingy> thingyRoot = query.from(Thingy.class);
Path<DateTime> setup = root.get("setup");
Path<DateTime> release = root.get("release");
Expression secondLiteral = criteriaBuilder.literal("SECOND");
Expression func = criteriaBuilder.function("TIMESTAMPDIFF", Integer.class, secondLiteral, setup, release);
entityManager.createQuery(query).getResultList();
但是,当我尝试运行此代码时,它引发了异常;看来文字没有呈现为常量,而是呈现为参数:
java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: '('
+-[METHOD_NAME] IdentNode: 'TIMESTAMPDIFF' {originalText=TIMESTAMPDIFF}
\-[EXPR_LIST] SqlNode: 'exprList'
+-[NAMED_PARAM] ParameterNode: '?' {name=param0, expectedType=null}
+-[DOT] DotNode: 'cdr0_.setup' {propertyName=setup,dereferenceType=ALL,propertyPath=setup,path=generatedAlias0.setup,tableAlias=cdr0_,className=com.vtsl.domain.CDR,classAlias=generatedAlias0}
| +-[ALIAS_REF] IdentNode: 'cdr0_.id' {alias=generatedAlias0, className=com.vtsl.domain.CDR, tableAlias=cdr0_}
| \-[IDENT] IdentNode: 'setup' {originalText=setup}
\-[DOT] DotNode: 'cdr0_.release' {propertyName=release,dereferenceType=ALL,propertyPath=release,path=generatedAlias0.release,tableAlias=cdr0_,className=com.vtsl.domain.CDR,classAlias=generatedAlias0}
+-[ALIAS_REF] IdentNode: 'cdr0_.id' {alias=generatedAlias0, className=com.vtsl.domain.CDR, tableAlias=cdr0_}
\-[IDENT] IdentNode: 'release' {originalText=release}
所以我尝试匿名覆盖LiteralExpression#render 以直接返回我提供给该方法的字符串,但是出现了这个异常。
java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: '('
+-[METHOD_NAME] IdentNode: 'TIMESTAMPDIFF' {originalText=TIMESTAMPDIFF}
\-[EXPR_LIST] SqlNode: 'exprList'
+-[IDENT] IdentNode: 'SECOND' {originalText=SECOND}
+-[DOT] DotNode: 'cdr0_.setup' {propertyName=setup,dereferenceType=ALL,propertyPath=setup,path=generatedAlias0.setup,tableAlias=cdr0_,className=com.vtsl.domain.CDR,classAlias=generatedAlias0}
| +-[ALIAS_REF] IdentNode: 'cdr0_.id' {alias=generatedAlias0, className=com.vtsl.domain.CDR, tableAlias=cdr0_}
| \-[IDENT] IdentNode: 'setup' {originalText=setup}
\-[DOT] DotNode: 'cdr0_.release' {propertyName=release,dereferenceType=ALL,propertyPath=release,path=generatedAlias0.release,tableAlias=cdr0_,className=com.vtsl.domain.CDR,classAlias=generatedAlias0}
+-[ALIAS_REF] IdentNode: 'cdr0_.id' {alias=generatedAlias0, className=com.vtsl.domain.CDR, tableAlias=cdr0_}
\-[IDENT] IdentNode: 'release' {originalText=release}
所以问题是:我怎样才能修复我正在尝试做的这个操作,或者实现最初的目标?
我正在使用 Hibernate,我的数据库是 MySQL。
【问题讨论】:
-
嗨@WiseTree,我在使用 grails+hibernate+MySQL 时也面临同样的问题。如果您有解决方案,您可以发布它吗? -谢谢
-
我遇到这个问题的软件被推迟了,所以不幸的是,我在弄清楚之前就停止了这个工作。
-
对于这么简单的请求,我真的不知道该笑还是该哭。 JPA 的建设者们一定是对 SQL 恨之入骨。我遇到了同样的问题,但仍然没有办法(除了希望数据库中的任何内容都不会超过 35 天)
标签: java mysql sql hibernate jpa