使用EclipseLink进行Join ... ON子句+子查询的JPQL查询,结果出现异常 "编译时遇到内部问题"。

问题描述 投票:0回答:1

我有一个JPQL查询,其中有一个 JOIN ... ON ... 子句,从JPA 2.1开始有效。

SELECT NEW net.bbstats.dto.CompetitionListDto(
  gl.name,
  se.startYear,
  -1,
  cm.level,
  cml.code,
  cml.name,
  tt.code,
  tt.ageGroup,
  tt.gender,
  cm.type,
  -1
)
FROM Group gr
  LEFT JOIN gr.groupLabel gl
  LEFT JOIN gr.groupMembers gm
  LEFT JOIN gm.roster ro
  JOIN gr.round rd
  JOIN rd.season se
  JOIN rd.competition cm
  JOIN cm.teamType tt
  JOIN cm.geoContext gc
  JOIN cm.competitionLabels cml ON cml.seasonStartYear = SELECT MAX(lbl.seasonStartYear)
                                                          FROM CompetitionLabel lbl
                                                            JOIN lbl.competition cmp
                                                            JOIN cmp.geoContext geo
                                                            JOIN cmp.teamType tet
                                                          WHERE geo.id = ge.id
                                                            AND tet.code = tt.code
                                                            AND cmp.type = cm.type
                                                            AND cmp.level = cm.level
                                                            AND lbl.seasonStartYear <= :seasonStartYear
WHERE se.startYear = :seasonStartYear
GROUP BY rd.id, gl.code, cml.code, cml.name
ORDER BY se.startYear, gc.type, gc.name, cm.type, tt.ageGroup DESC, tt.gender DESC, rd.id, gl.code

我得到一个异常。

Exception Description: Unable to deploy PersistenceUnit [BBStatsPU] in invalid state [DeployFailed].
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.7.5.v20191016-ea124dd158): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Deployment of PersistenceUnit [BBStatsPU] failed. Close all factories for this PersistenceUnit.
Internal Exception: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.5.v20191016-ea124dd158): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Internal problem encountered while compiling [
            SELECT NEW net.bbstats.dto.CompetitionListDto(
              gl.name,
              se.startYear,
              -1,
              cm.level,
              cml.code,
              cml.name,
              tt.code,
              tt.ageGroup,
              tt.gender,
              cm.type,
              -1
            )
            FROM Group gr
              LEFT JOIN gr.groupLabel gl
              LEFT JOIN gr.groupMembers gm
              LEFT JOIN gm.roster ro
              JOIN gr.round rd
              JOIN rd.season se
              JOIN rd.competition cm
              JOIN cm.teamType tt
              JOIN cm.geoContext gc
              JOIN cm.competitionLabels cml ON cml.seasonStartYear = SELECT MAX(lbl.seasonStartYear)
                                                                      FROM CompetitionLabel lbl
                                                                        JOIN lbl.competition cmp
                                                                        JOIN cmp.geoContext geo
                                                                        JOIN cmp.teamType tet
                                                                      WHERE geo.id = ge.id
                                                                        AND tet.code = tt.code
                                                                        AND cmp.type = cm.type
                                                                        AND cmp.level = cm.level
                                                                        AND lbl.seasonStartYear <= :seasonStartYear
            WHERE se.startYear = :seasonStartYear
            GROUP BY rd.id, gl.code, cml.code, cml.name
            ORDER BY se.startYear, gc.type, gc.name, cm.type, tt.ageGroup DESC, tt.gender DESC, rd.id, gl.code
        ].
Internal Exception: java.lang.NullPointerException
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:634)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:222)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:330)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:350)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)
    at org.jboss.as.jpa.container.TransactionScopedEntityManager.createEntityManager(TransactionScopedEntityManager.java:187)
    at org.jboss.as.jpa.container.TransactionScopedEntityManager.getOrCreateTransactionScopedEntityManager(TransactionScopedEntityManager.java:157)
    at org.jboss.as.jpa.container.TransactionScopedEntityManager.getEntityManager(TransactionScopedEntityManager.java:87)
    at org.jboss.as.jpa.container.AbstractEntityManager.createNamedQuery(AbstractEntityManager.java:98)
    at net.bbstats.framework.service.Repository.findByNamedQuery(Repository.java:173)
    at net.bbstats.framework.service.BaseEntityService.findByNamedQuery(BaseEntityService.java:467)
    at net.bbstats.framework.service.BaseEntityService.findByNamedQuery(BaseEntityService.java:453)
    at net.bbstats.framework.service.BaseEntityService.findByNamedQuery(BaseEntityService.java:429)
    at net.bbstats.framework.service.BaseEntityService.findAllWithFetchGraph(BaseEntityService.java:385)
    ... 192 more

在JPA 2.1规范的JPQL BNF中,可以看到: https:/download.oracle.comotn-pubjcppersistence-2_1-fr-eval-specJavaPersistence.pdf?#G4.1537490。జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ JOIN ... ON ... 似乎并不允许在右侧的 join_condition 如果进一步评估。

enter image description here

问题:

我的假设是否正确?

如果是,那么我将如何使用标准JPA+EclipseLink解决我手头的问题? 原生查询(这将是一个明显的选择)?

解释一下:子查询采用一个赛季开始的年份作为参数,比如说2010年,然后将确定比赛的最新名称标签,这个标签可能是在2005年插入的。例如,像德国篮球德甲联赛这样的比赛,可能每隔X年就会更换赞助商,所以2010年的名称可能是 "Beko篮球德甲联赛",从2014年开始就会变成 "easycredit BBL "等等。

简单的版本 "获取所有在通过之前的MAX标签实体。:seasonStartYear"

BTW:上面的查询使用Hibernate工作。EclipseLink的版本是2.7.5,见stacktrace。

hibernate jpa eclipselink jpql jpa-2.1
1个回答
1
投票

EclipseLink根本不支持这个。由于你使用的是内部连接,实际上你也可以在WHERE子句中使用子查询,就像这样。

SELECT NEW net.bbstats.dto.CompetitionListDto(
  gl.name,
  se.startYear,
  -1,
  cm.level,
  cml.code,
  cml.name,
  tt.code,
  tt.ageGroup,
  tt.gender,
  cm.type,
  -1
)
FROM Group gr
  LEFT JOIN gr.groupLabel gl
  LEFT JOIN gr.groupMembers gm
  LEFT JOIN gm.roster ro
  JOIN gr.round rd
  JOIN rd.season se
  JOIN rd.competition cm
  JOIN cm.teamType tt
  JOIN cm.geoContext gc
  JOIN cm.competitionLabels cml
WHERE se.startYear = :seasonStartYear
AND cml.seasonStartYear = (SELECT MAX(lbl.seasonStartYear)
                                                          FROM CompetitionLabel lbl
                                                            JOIN lbl.competition cmp
                                                            JOIN cmp.geoContext geo
                                                            JOIN cmp.teamType tet
                                                          WHERE geo.id = ge.id
                                                            AND tet.code = tt.code
                                                            AND cmp.type = cm.type
                                                            AND cmp.level = cm.level
                                                            AND lbl.seasonStartYear <= :seasonStartYear)
GROUP BY rd.id, gl.code, cml.code, cml.name
ORDER BY se.startYear, gc.type, gc.name, cm.type, tt.ageGroup DESC, tt.gender DESC, rd.id, gl.code
© www.soinside.com 2019 - 2024. All rights reserved.