我有一个实体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]