我有两个简单的模型:
class Parent {
Long id; //auto generated sequence and primary key
String name;
Set<Child> children;
}
class Child {
String name;
Long parent_id; //foreign key
}
我有一个像这样的hql查询:
FROM Parent p
left join fetch p.children as children
WHERE p.name = 'John'
'children'是父模型中'Child'模型的集合(集合)。
如果'John'有2个孩子,则上述查询的结果通过执行单个查询给出了2个父母(相同参考)的列表,每个父母有2个孩子。
我正在尝试通过下面的Criteria API实现相同的目标:
Criteria c = session.createCriteria(Parent.class);
c.setFetchMode("children", FetchMode.JOIN);
c.createCriteria("children", Criteria.LEFT_JOIN);
c.add(Restrictions.eq("name", "John"));
c.scroll();
使用上面的代码,我得到2个父实例(相同的引用)的列表,只有1个子元素(而不是预期的2)执行单个sql查询。
我在api做错了什么?当我看到生成的sql时,它是一样的。
答案 0 :(得分:1)
我遇到了同样的问题,经过Hibernate代码调试后,我认为这是一个Hibernate错误,而不是你做错了什么。
它已在this Hibernate issue中修复,但我们的Criteria仍然在可滚动结果中返回不完整的子集合。我发现在Loader
类中有一些逻辑决定是否使用FetchingScrollableResultsImpl
来正确处理行,而CriteriaLoader
它永远不会,因为needsFetchingScroll()
总是返回false 。但是,QueryLoader
确实在使用连接提取时使用它,这就是为什么将我们的标准转换为HQL为我们解决了这个问题。
我打算用Hibernate提交一个bug来实现CriteriaLoader.needsFetchingScroll()
。
答案 1 :(得分:0)
我有类似的情况,这里是相同的代码(至少在我的情况下):
Criteria c = session.createCriteria(Parent.class);
c.setFetchMode("children", FetchMode.JOIN);
c.add(Restrictions.eq("name", "John"));
List<Parent> list = c.list();
Iterator<Parent> iter = list.iterator();
我有这样的印象
c.scroll();
强制执行与c.setResultTransformer( Criteria.DISTINCT_ROOT_ENTITY );