Hibernate Criteria API结果与左连接提取的HQL结果不匹配

时间:2011-06-23 02:04:00

标签: hibernate criteria left-join criteria-api

我有两个简单的模型:

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时,它是一样的。

2 个答案:

答案 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 );

类似的行为