JPA / JPQL:SELECT子句中不允许使用AS标识符

时间:2012-08-04 10:13:52

标签: hibernate select jpa jpql

我有一个非常复杂的形式

的JPQL查询
  SELECT NEW com.domain.project.view.StandingsStatLine(
      ro.id                                                                                                 AS rid
    , cl.name                                                                                               AS team
    , te.ordinalNbr + 1                                                                                     AS nr
    , pa.wasWithdrawn                                                                                       AS wd

    , SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1 ELSE 0 END)                                           AS g
    , SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore > sca.finalScore THEN 1 ELSE 0 END)                                      AS w
    , SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore < sca.finalScore THEN 1 ELSE 0 END)                                      AS l
    , SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore = 20 AND sca.finalScore =  0 THEN 1 ELSE 0 END)                          AS wbr
    , SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore =  0 AND sca.finalScore = 20 THEN 1 ELSE 0 END)                          AS lbr
    , SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore =  0 AND sca.finalScore =  0 THEN 1 ELSE 0 END)                          AS blbr

    , SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore > sca.finalScore THEN 1 ELSE 0 END)
      + SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1 ELSE 0 END)
      - SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore = 0 AND sca.finalScore = 20 THEN 1 ELSE 0 END)                         AS rp
    , CASE WHEN (  SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore > sca.finalScore THEN 1 ELSE 0 END)
                 + SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1 ELSE 0 END)
                 - SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore = 0 AND sca.finalScore = 20 THEN 1 ELSE 0 END)
                 - SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1 ELSE 0 END))
                   / SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1.0 ELSE 0.0 END) >= 0.0
           THEN ((  SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore > sca.finalScore THEN 1 ELSE 0 END)
                 + SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1 ELSE 0 END)
                 - SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore = 0 AND sca.finalScore = 20 THEN 1 ELSE 0 END)
                 - SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1 ELSE 0 END))
                   / SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1.0 ELSE 0.0 END))
           ELSE 0.0 END                                                                                                                                               AS nrp
    , CASE WHEN SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1 ELSE 0 END) > 0
           THEN  (SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore > sca.finalScore THEN 1.0 ELSE 0.0 END)
                / SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN 1 ELSE 0 END))
           ELSE NULL END                                                                                                                                              AS wperc

    , SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore IS NOT NULL THEN scf.finalScore ELSE 0 END)                              AS ptsf
    , SUM(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND sca.finalScore IS NOT NULL THEN sca.finalScore ELSE 0 END)                              AS ptsa

    , MAX(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore NOT IN (0, 20) THEN scf.finalScore ELSE NULL END)                        AS hi
    , MAX(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore NOT IN (0, 20) THEN scf.game.id ELSE NULL END)                           AS higid
    , MIN(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore NOT IN (0, 20) THEN scf.finalScore ELSE NULL END)                        AS lo
    , MIN(CASE WHEN paf.wasWithdrawn = FALSE AND paa.wasWithdrawn = FALSE AND scf.finalScore NOT IN (0, 20) THEN scf.game.id ELSE NULL END)                           AS logid
    )
  FROM Club cl
    JOIN cl.teams te
    JOIN te.rosters ro
    JOIN ro.season se
    JOIN ro.participations pa
    JOIN pa.group gr
    JOIN gr.round rd
    JOIN rd.subCompetition sc
    JOIN sc.competition cn
    JOIN gr.games ga
    JOIN ga.scores scf
    JOIN ga.scores sca
    JOIN scf.roster rof
    JOIN sca.roster roa
    JOIN rof.participations paf
    JOIN roa.participations paa
  WHERE ...
  GROUP BY ...
  ORDER BY pa.wasWithdrawn, nrp DESC, w DESC, lbr, g DESC, cl.shorthand

使用Hibernate 4.x运行它可以正常工作,但Eclipse Dali几乎在构造函数表达式的每一行都显示JPQL错误。删除... AS <identifier>可以消除这些错误。

我在这里查看了JPQL BNF http://en.wikibooks.org/wiki/Java_Persistence/JPQL_BNF,但是在SELECT子句层次结构中找不到AS

问的:

这是特定于Hibernate的语法吗?

为什么JPQL不支持这个?

有时表达式会变得非常复杂,我想通过AS子句记录表达式的实际含义,特别是考虑到JPQL没有注释功能。这是JPQL恕我直言中的一个真正的缺陷。

此外,Hibernate允许我在AS子句中引用这些ORDER BY es,这允许我重用上面的复杂语句。

也许我的表达可以缩短,但在其他情况/项目中复杂性仍然很高。

由于

1 个答案:

答案 0 :(得分:2)

找到它。

根据http://en.wikibooks.org/wiki/Java_Persistence/JPQL_BNF#New_in_JPA_2.0的JPQL BNF,这应该得到JPA 2.0的支持。注意,倒数第二个例子。

这几乎解答了为什么Eclipse Dali显示JPQL验证错误的原始问题。这似乎是达利的一个问题。