Боюсь, что я, возможно, плохо сформулировал свой предыдущий вопрос , поэтому я начинаю заново для ясности.
Изобразите количество таблиц, для которых существует связь 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 выполняется с подзапросом на каждой итерации, который не включает ограничение, поэтому я получаю все Regions из 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]