【问题标题】:JPQL/HQL and JPA/Hibernate: boolean expression in select constructor expression not working (unexpected AST node: AND, NPE, HqlSqlWalker.setAlias)?JPQL/HQL 和 JPA/Hibernate:选择构造函数表达式中的布尔表达式不起作用(意外的 AST 节点:AND、NPE、HqlSqlWalker.setAlias)?
【发布时间】:2011-06-25 17:38:10
【问题描述】:

我有一个 JPQL 语句来返回体育比赛的时间表:

SELECT NEW com.kawoolutions.bbstats.view.ScheduleGameLine(
    ga.id                                                                                           AS gid
  , ga.scheduledTipoff                                                                              AS scheduledtipoff
  ...
  , sch.finalScore                                                                                  AS homefinalscore
  , sca.finalScore                                                                                  AS awayfinalscore
  , sch.finalScore IS NOT NULL AND sca.finalScore IS NOT NULL                              AS hasfinalscore
)

我希望最后一个表达式 (boolean) 评估为一个布尔值,以指示游戏的最终得分是否已完全报告(Score 类型的两个实体,这里 sch 和 sca 表示主客场得分)。但是,Hibernate 失败并出现异常:

11.02.2011 18:40:16 org.hibernate.hql.ast.ErrorCounter reportError
SCHWERWIEGEND: <AST>:17:32: unexpected AST node: AND
Exception in thread "main" java.lang.NullPointerException
    at org.hibernate.hql.ast.HqlSqlWalker.setAlias(HqlSqlWalker.java:1000)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.aliasedSelectExpr(HqlSqlBaseWalker.java:2381)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.constructor(HqlSqlBaseWalker.java:2505)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2256)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:2121)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1522)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:593)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:244)
    at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:254)
    at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:185)
    at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124)
    at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
    at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
    at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1770)
    at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:272)
    at com.kawoolutions.bbstats.Main.executeJpqlStatement(Main.java:167)
    at com.kawoolutions.bbstats.Main.main(Main.java:154)

当用 CASE WHEN 包围最后一个表达式以返回 TRUE 或 FALSE 时,我得到了我期望的结果:

SELECT NEW com.kawoolutions.bbstats.view.ScheduleGameLine(
    ga.id                                                                                           AS gid
  , ga.scheduledTipoff                                                                              AS scheduledtipoff
  ...
  , sch.finalScore                                                                                  AS homefinalscore
  , sca.finalScore                                                                                  AS awayfinalscore
  , CASE WHEN sch.finalScore IS NOT NULL AND sca.finalScore IS NOT NULL THEN TRUE ELSE FALSE END    AS hasfinalscore
  )

我真的很想知道为什么这不适用于 CASE WHEN。这里有什么问题?那是我吗?是JPA吗?是休眠吗?错误?

【问题讨论】:

    标签: hibernate jpa hql jpql boolean-expression


    【解决方案1】:

    它看起来像一个指定的行为。 JPA 根本不允许在 SELECT 子句中使用条件表达式,但允许 CASE 表达式。

    这是来自JPA Specification的JPQL语法的相关部分:

    选择表达式 ::=
        单值路径表达式 |
        标量表达式 |
        聚合表达式 |
        识别变量 |
        对象(标识变量)|
        构造函数表达式
    
    构造函数表达式 ::=
        新的constructor_name(constructor_item {,constructor_item}*)
    
    构造器项目 ::=
        单值路径表达式 |
        标量表达式 |
        聚合表达式 |
        识别变量
    
    标量表达式 ::=
        simple_arithmetic_expression |
        string_primary |
        enum_primary |
        datetime_primary |
        boolean_primary |
        案例表达式 |
        entity_type_expression

    【讨论】:

    • 什么是 boolean_primary?引用的布尔成员(这些确实有效)?
    • @Kawu:它是布尔字面量(TRUEFALSE)、输入参数和布尔属性。
    猜你喜欢
    • 2017-09-02
    • 2012-09-28
    • 2013-11-16
    • 2017-08-21
    • 2022-06-10
    • 1970-01-01
    • 2018-09-03
    • 2015-04-29
    • 1970-01-01
    相关资源
    最近更新 更多