我担心我的previous question措词可能不好,所以为了清楚起见,我从头开始。
想象一些表,每个表之间都有一个OneToMany关联;场->字段-> RegionGroup->区域。我正在尝试构造一个Criteria查询,该查询将对Region。营养进行过滤。我已经看到了很多人的示例,这些人员在顶层(有时是下一层)的属性上进行过滤,但是不确定在过滤四层时如何构造查询。目前我有这个,这是行不通的。
Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Farm.class)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
.setFetchMode("fields.regionGroups", FetchMode.JOIN)
.setFetchMode("fields.regionGroups.regions", FetchMode.JOIN)
.createCriteria("fields.regionGroups.regions").add(Restrictions.in("nutrient", nutrients));
发生的结果是,生成了一个主SQL查询,该查询正确覆盖了所需的结果(并且恰好是应检索的数据集),但是,当您迭代返回的对象时,RegionGroup-> Region的关联使用每次迭代的子查询都没有限制,因此我获得RegionGroup的所有Region,而与Region。营养值无关;
select
...
from
Farm this_
inner join
Business business3_ on this_.BusinessID=business3_.BusinessID
left outer join
Field fields4_ on this_.FarmID=fields4_.FarmID
left outer join
RegionGroup regiongrou5_ on fields4_.FieldID=regiongrou5_.FieldID
inner join
Region region1_ on regiongrou5_.RegionGroupID=region1_.RegionGroupID
where
region1_.nutrient in ( ? )
-------------------------------------------
select
...
from
Region regions0_
where
regions0_.RegionGroupID=?
我需要添加什么,以便对关联路径“ fields.regionGroups.regions”执行指定的限制?
编辑:下面的HQL可以执行我想要的操作,但是没有我想要的定义灵活性,因此我想将其转换为Criteria查询;
from Farm as farm
inner join fetch farm.fields as field
inner join fetch field.regionGroups as regionGroup
inner join fetch regionGroup.regions as region
where farm.id in :farmId
and field.id in :fieldId
and region.nutrient in :nutrients
这给了我一个输出
List<Farm>
,因此可以对其进行迭代;Farm [shortName=XYZ, name=XYZ]
Field [shortName=COMM, name=Common]
RegionGroup [indexNo=1]
Region [nutrient=P, nutrientLevel=18.869684]
RegionGroup [indexNo=2]
Region [nutrient=P, nutrientLevel=18.836086]
RegionGroup [indexNo=3]
Region [nutrient=P, nutrientLevel=18.954369]
那么,如何将其指定为条件查询?为了证明它正在执行我想要的操作,如果仅更改HQL并删除对Region。营养的限制,我将获取每个RegionGroup的所有Region;
from Farm as farm
inner join fetch farm.fields as field
inner join fetch field.regionGroups as regionGroup
inner join fetch regionGroup.regions as region
where farm.id in :farmId
and field.id in :fieldId
无需更改代码即可迭代结果,现在我得到了;
Farm [shortName=XYZ, name=XYZ]
Field [shortName=COMM, name=Common]
RegionGroup [indexNo=1]
Region [nutrient=Mg, nutrientLevel=108.84927]
Region [nutrient=P, nutrientLevel=18.869684]
Region [nutrient=pH, nutrientLevel=6.727207]
Region [nutrient=K, nutrientLevel=189.04442]
RegionGroup [indexNo=2]
Region [nutrient=Mg, nutrientLevel=108.6944]
Region [nutrient=pH, nutrientLevel=6.7214856]
Region [nutrient=K, nutrientLevel=188.38605]
Region [nutrient=P, nutrientLevel=18.836086]
RegionGroup [indexNo=3]
Region [nutrient=K, nutrientLevel=190.72464]
Region [nutrient=pH, nutrientLevel=6.736169]
Region [nutrient=P, nutrientLevel=18.954369]
Region [nutrient=Mg, nutrientLevel=109.54382]
最佳答案
让我说清楚-您是否期望在返回的Farm
列表中它们只会填充一些Region
和RegionGroup
?
换句话说,假设我有一个带有2个Farm
的Field
,每个都有2个RegionGroup
,每个都有2个Region
,而您正在寻找的这些Region's has the
营养物中只有1个。
当您运行查询时,您将获得该Farm
实例(如您所愿-它满足条件)。现在,您是否希望该实例只有1个Field
且其中1个RegionGroup
和1个Region
包含您的营养素?
那不会-不会发生。 Hibernate保证对象的内存表示形式与其持久状态(当然是后刷新)相匹配,并且执行上述操作与该原理相矛盾。如果可能的话,在您决定修改并保存该Farm
后会发生什么? Hibernate现在是否应该从数据库中删除所有其他Field
/ etc ...?
如果这不是您要的内容,请澄清您的问题。