我担心我之前的问题可能表述得很糟糕,所以为了清楚起见,我重新开始。
想象许多表,每个表之间存在 OneToMany 关联;农场 -> 田野 -> RegionGroup -> 地区。我正在尝试构建一个 Criteria 查询,该查询将在Region.nutrient上进行过滤。我已经看到很多人过滤顶层属性的例子,有时甚至是下一层,但我不确定在过滤四层深度时如何构造查询。目前我有这个,这是行不通的;
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.nutrient的值无关;
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.nutrient 的限制,我会取回每个 RegionGroup 的所有区域;
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]