我有2点简单的模型:不匹配HQL结果左Hibernate的标准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'
'孩子' 是一个集合(在Parent模型中设置'Child'模型。
如果'John'有2个孩子,通过执行单个查询,上面查询的结果给出了每个有2个孩子的2个父母(相同引用)的列表。
我想实现通过标准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 )bu执行单个sql查询。
我在做什么错误的API?当我看到生成的sql时,它是一样的。
看起来这与'c.scroll()'和'c.list()'有关,而不是HQL和Criteria API之间的区别。当我发布这个问题时,我使用'query.list()'作为HQL,'c.scroll()'作为Criteria API。现在我尝试了所有4种组合,发现只有c.scroll()以意想不到的方式行事。我不明白为什么或如何解决它。 – Bhargava
看起来在'scroll'期间,'session'只查看缓存中的父标识符,而没有用新的子关联来更新它。但是'list'似乎正在用新的子关联更新缓存的父对象。我的推理是,它不希望为同一个对象提供2种不同的状态,因此如果在进一步滚动期间再次遇到缓存对象,它不会更新缓存对象。我对吗?我试过'c.setCacheable(false)'/'c.setCacheable(true); c.setCacheMode(CacheMode.IGNORE/REFRESH)'但不起作用。 – Bhargava
它看起来像我需要滚动有序的父列表和订购与2查询的子列表,他们合并它们programmatic-ally冬眠外。我想知道是否有更好的方法。 – Bhargava