3

我担心我之前的问题可能表述得很糟糕,所以为了清楚起见,我重新开始。

想象许多表,每个表之间存在 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]
4

2 回答 2

0

I have similar goal to fetch list of objects from the 3rd level with criteria matching 2 parameters: 1st id of the main parent entity and 2nd id of the inner most entity. This is the question (sorry I could only add it in the answer section as I wanted to get quicker attention and solution to my original question and I am unable to post it as a comment due to lower reputation on my profile). Thanks.

于 2015-03-15T11:16:19.313 回答
0

让我直截了当地说 - 您是否期望在返回的Farms 列表中它们只会填充一些 Regions 和s ?RegionGroup

换句话说,假设我有一个Farm2 Fields,每个都有 2 RegionGroups,每个都有 2 Regions,并且只有 1 个Region's has the您正在寻找的营养素。

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

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

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

于 2011-08-04T17:55:24.500 回答