2

フォームのかなり複雑な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

これをHibernate4.xで実行すると問題なく動作しますが、EclipseDaliはコンストラクター式のほぼすべての行でJPQLエラーを示します。を削除する... AS <identifier>と、これらのエラーがなくなります。

ここでJPQLBNFhttp ://en.wikibooks.org/wiki/Java_Persistence/JPQL_BNFASを確認しましたが、SELECT句の階層にが見つかりませんでした。

Q:

これはHibernate固有の構文ですか?

JPQLがこれをサポートしないのはなぜですか?

AS式が非常に複雑になることがあります。特にJPQLにはコメント機能がないことを考えると、式が実際に何を意味するのかを句で文書化したいと思います。これはJPQLIMHOの本当の欠陥です。

さらに、Hibernateを使用するASと、句でこれらのesを参照できるORDER BYため、上記の複雑なステートメントを再利用できます。

たぶん私の表現は短くなるかもしれませんが、他のケース/プロジェクトではまだ複雑さが高い可能性があります。

ありがとう

4

1 に答える 1

2

それを見つけた。

http://en.wikibooks.org/wiki/Java_Persistence/JPQL_BNF#New_in_JPA_2.0の JPQL BNF によると、これは JPA 2.0 でサポートされるはずです。最後から 2 番目の例に注意してください。

これは、なぜ Eclipse Dali が JPQL 検証エラーを表示するのかという元の質問にほとんど答えています。ダリに問題があるようです。

于 2012-08-05T17:02:20.137 に答える