2012-08-04 22 views
1

不允许我有形式JPA/JPQL:AS标识在SELECT子句

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 

的相当复杂的JPQL查询与Hibernate 4.x的运行此工程没有问题,但是Eclipse的大理显示了一个漂亮的JPQL错误构造函数表达式的每一行。删除... AS <identifier>可以消除这些错误。

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

Q记者:

这是Hibernate的相关语法?

为什么JPQL不支持这个?

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

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

也许我的表情可能会缩短,但其他情况/项目的复杂度仍然很高。

谢谢

+0

有点偏离主题,但如果您的目标是让查询更具可读性,那么您为什么使用像'te','se','nrp','w'这些令人难以置信的神秘缩写?作为您的查询的随便读者,我有根本不知道'g ORDER应该订购什么。 – 2012-08-04 12:06:31

+0

是的,我同意你的看法,所选的缩写非常笨拙。这些都是针对篮球的:g =游戏,w =胜,l =损失等。对篮球运动员来说,大多数都是可以理解的,但nrp =规范化的排名点超出了范围。我会将其作为端口的一部分进行更改,因为我必须自己查找nrp:o)看起来'AS ...'不是JPA。我只是想知道如何在'ORDER BY'子句中使用这些表达式...: -/ – Kawu 2012-08-04 16:30:26

回答

1

找到它了。

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

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

+0

Dali使用的是什么版本?也许这是在更新的版本中修复的。 – 2012-08-05 19:12:35

+0

Indigo版本目前可用。它的内容是:'Dali Java持久工具 - JPA支持 版本:3.0.2.v201110193010-7S7B7HFC7sRdlV6fmbQaRBF5 构建ID:20120210195245 '...无论出于何种原因,Dali版似乎相当老旧。我最近升级了Eclipse,然后获得了Juno版本。上次安装恢复,然后手动检查更新说“没有更新可用”。我可能不得不重试。但我不能去朱诺。 – Kawu 2012-08-06 16:58:57