我担心我的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列表中它们只会填充一些RegionRegionGroup

换句话说,假设我有一个带有2个FarmField,每个都有2个RegionGroup,每个都有2个Region,而您正在寻找的这些Region's has the营养物中只有1个。

当您运行查询时,您将获得该Farm实例(如您所愿-它满足条件)。现在,您是否希望该实例只有1个Field且其中1个RegionGroup和1个Region包含您的营养素?

那不会-不会发生。 Hibernate保证对象的内存表示形式与其持久状态(当然是后刷新)相匹配,并且执行上述操作与该原理相矛盾。如果可能的话,在您决定修改并保存该Farm后会发生什么? Hibernate现在是否应该从数据库中删除所有其他Field / etc ...?

如果这不是您要的内容,请澄清您的问题。

09-05 00:49