从JPQL查询生成错误的SQL

时间:2015-02-04 15:03:52

标签: java hibernate jpa

我有一个实体DetectorGroup,它有一组子项,也是DetectorGroup个。这是我的Hibernate映射(我使用的是Hibernate 4.2):

<class name="DetectorGroup" table="DetectorGroup">
        <id name="m_id" type="int" column="id" unsaved-value="-1">
            <generator class="native"/>
        </id>
        <property name="m_name" column="name" not-null="true"/>
        <set name="m_detectors" table="DetectorAssignedToDetectorGroup" lazy="false" cascade="none">
            <key column="groupId"/>
            <many-to-many column="detectorId" class="AbstractDetector" />
        </set>
        <set name="m_childGroups" lazy="false" inverse="true" cascade="merge,save-update">
            <key column="parentId" not-null="false" />
            <one-to-many class="DetectorGroup"/>
        </set>

        <set name="m_users" lazy="false" cascade="none" table="DetectorGroupUser">
            <key column="detectorGroupId"   />
            <many-to-many class="com.mycompany.domain.authentication.User" column="userId" />
        </set>

        <many-to-one name="m_parentGroup" class="DetectorGroup" column="parentId" lazy="false"/>
    </class>

我的基本设置正常工作,所以像这样的方法可以正常工作:

public Set<Integer> getDetectorIdsInGroup()
    {
        return Sets.newHashSet( m_entityManager.createQuery( "select detector.m_id from DetectorGroup g join g.m_detectors detector", Integer.class ).getResultList() );
    }

但是,现在我想获得一个DetectorGroups集合,其中引用了给定的Detectors集合。这是我想要实现的方法签名:

public Set<DetectorGroup> getDetectorGroupsContainingDetectors( Iterable<Detector> detectors )

我尝试使用JPQL:

    return Sets.newHashSet( m_entityManager.createQuery( "from DetectorGroup g where g.m_parentGroup is null and g.m_detectors in :detectors ", DetectorGroup.class )
                                    .setParameter( "detectors", detectors )
                                    .getResultList() );

我也试过了CriteriaBuilder

    CriteriaBuilder builder = m_entityManager.getCriteriaBuilder();
    CriteriaQuery<DetectorGroup> query = builder.createQuery( DetectorGroup.class );
    Root<DetectorGroup> detectorGroupRoot = query.from( DetectorGroup.class );
    query.where( detectorGroupRoot.get( "m_parentGroup" ).isNull(),
                 detectorGroupRoot.get( "m_detectors").in( detectors ) );
    return Sets.newHashSet( m_entityManager.createQuery( query ).getResultList() );

两者都给出了相同的结果:

2015-02-04 15:46:34 DEBUG [main] QueryTranslatorImpl - HQL: select generatedAlias0 from com.traficon.domain.detector.DetectorGroup as generatedAlias0 where ( generatedAlias0.m_parentGroup is null ) and ( generatedAlias0.m_detectors in (:param0) )
2015-02-04 15:46:34 DEBUG [main] QueryTranslatorImpl - SQL: select detectorgr0_.id as id1_19_, detectorgr0_.name as name2_19_, detectorgr0_.parentId as parentId3_19_ from DetectorGroup detectorgr0_ cross join DetectorAssignedToDetectorGroup m_detector1_, Detector abstractde2_ where detectorgr0_.id=m_detector1_.groupId and m_detector1_.detectorId=abstractde2_.id and (detectorgr0_.parentId is null) and (. in (?))
2015-02-04 15:46:34 DEBUG [main] ErrorCounter - throwQueryException() : no errors
2015-02-04 15:46:34 DEBUG [main] SQL - select detectorgr0_.id as id1_19_, detectorgr0_.name as name2_19_, detectorgr0_.parentId as parentId3_19_ from DetectorGroup detectorgr0_ cross join DetectorAssignedToDetectorGroup m_detector1_, Detector abstractde2_ where detectorgr0_.id=m_detector1_.groupId and m_detector1_.detectorId=abstractde2_.id and (detectorgr0_.parentId is null) and (. in (?))
2015-02-04 15:46:34 DEBUG [main] SqlExceptionHelper - could not prepare statement [select detectorgr0_.id as id1_19_, detectorgr0_.name as name2_19_, detectorgr0_.parentId as parentId3_19_ from DetectorGroup detectorgr0_ cross join DetectorAssignedToDetectorGroup m_detector1_, Detector abstractde2_ where detectorgr0_.id=m_detector1_.groupId and m_detector1_.detectorId=abstractde2_.id and (detectorgr0_.parentId is null) and (. in (?))]
org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "SELECT DETECTORGR0_.ID AS ID1_19_, DETECTORGR0_.NAME AS NAME2_19_, DETECTORGR0_.PARENTID AS PARENTID3_19_ FROM DETECTORGROUP DETECTORGR0_ CROSS JOIN DETECTORASSIGNEDTODETECTORGROUP M_DETECTOR1_, DETECTOR ABSTRACTDE2_ WHERE DETECTORGR0_.ID=M_DETECTOR1_.GROUPID AND M_DETECTOR1_.DETECTORID=ABSTRACTDE2_.ID AND (DETECTORGR0_.PARENTID IS NULL) AND (.[*] IN (?)) "; expected "), NOT, EXISTS, SELECT, FROM"; SQL statement:
select detectorgr0_.id as id1_19_, detectorgr0_.name as name2_19_, detectorgr0_.parentId as parentId3_19_ from DetectorGroup detectorgr0_ cross join DetectorAssignedToDetectorGroup m_detector1_, Detector abstractde2_ where detectorgr0_.id=m_detector1_.groupId and m_detector1_.detectorId=abstractde2_.id and (detectorgr0_.parentId is null) and (. in (?)) [42001-168]

这是使用H2数据库的单元测试。

注意最后在SQL中生成的奇怪事情:

(detectorgr0_.parentId is null) and (. in (?))

我做错了吗?这可能是一个Hibernate错误吗?

更新:

即使像这样的简单查询也会产生类似的问题:

m_entityManager.createQuery( "update DetectorGroup dg set dg.m_detectors = null" ).executeUpdate();

错误:

2015-02-04 16:29:49 ERROR [main] SqlExceptionHelper - Syntax error in SQL statement "UPDATE DETECTORGROUP CROSS[*] JOIN  SET .=NULL "; expected "., AS, SET"; SQL statement:
update DetectorGroup cross join  set .=null [42001-168]

0 个答案:

没有答案