JPQL/HQL и JPA/Hibernate: логическое выражение в выражении конструктора select не работает (неожиданный узел AST: AND, NPE, HqlSqlWalker.setAlias)?

У меня есть оператор 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
)

Я хочу, чтобы последнее выражение (логическое) оценивалось как логическое, чтобы указать, был ли полностью сообщен окончательный счет игры или нет (два объекта типа 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. Что здесь не так? Это я? Это ЯПА? Это спящий режим? Ошибка?


person Kawu    schedule 11.02.2011    source источник


Ответы (1)


Это похоже на заданное поведение. JPA вообще не допускает условных выражений в предложении SELECT, хотя допускает выражения CASE.

Вот соответствующая часть грамматики JPQL из спецификации JPA:

select_expression ::=
    single_valued_path_expression |
    scalar_expression |
    aggregate_expression |
    identification_variable |
    OBJECT(identification_variable) |
    constructor_expression

constructor_expression ::=
    NEW constructor_name ( constructor_item {, constructor_item}* )

constructor_item ::=
    single_valued_path_expression |
    scalar_expression |
    aggregate_expression |
    identification_variable

scalar_expression ::=
    simple_arithmetic_expression |
    string_primary |
    enum_primary |
    datetime_primary |
    boolean_primary |
    case_expression |
    entity_type_expression
person axtavt    schedule 11.02.2011
comment
Что такое boolean_primary? Упомянутый логический член (они работают)? - person Kawu; 12.02.2011
comment
@Kawu: это логические литералы (TRUE или FALSE), входные параметры и логические свойства. - person axtavt; 12.02.2011