2012-08-04 25 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