似乎这是一个标准问题,但搜索解决方案却没有成功。我有两个孩子集的父类Person
:
class Person {
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
Set<Dog> dogs;
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
Set<Cat> cats;
}
子类Cat
(类Dog
看起来相同):
class Cat {
private String name;
@ManyToOne(targetEntity = Person.class, fetch = FetchType.EAGER)
@JoinColumn(name = "PERSON_ID")
public Person getPerson() {
return person;
}
}
问题是什么当我尝试检索所有Persons
,Cat
名称等于'Fritz'时,Hibernate在表Cat
上创建连接查询,其名称为'Fritz'。一切看起来都不错,但是当我展开检索Person
时(在Idea调试器中),它包含仅{/ 1}}的单个实例(名称为'Fritz'),尽管{{1可以有多个Cat
。在扩展的同时,Hibernate向Person
表发出其他请求并检索与此Cats
链接的所有项目,并且此字段正确填充。如何强制Hibernate使用所有项目填充字段Dog
,而不仅仅是连接项目?
P.S。我使用的是Spring的HibernateTemplate session.get(),而不是HQL。
编辑1。生成的查询(第二部分仅在我在调试器中展开检索到的Person
时执行):
Cat
编辑2。似乎我的问题是前Hibernate bug。但我仍然需要帮助。我的Hibernate版本是4.3。
答案 0 :(得分:3)
我对使用调试器看看hibernate如何映射关联并不是很有信心。它使用按需填充的特殊集合,因为填充集合会产生额外的请求,而Hibernate会尝试在简单性和性能之间进行良好的混合。
所以当你要求*拥有Pussicat的人时,Hibernate只对表Person进行查询,除非你急切地加载子表,如果你列出那个人的猫狗,它只会对子表进行查询< strong>代码中没有调试器。
而且你知道你不能急切地加载所有关联。如果你这样做,任何简单的查询都可以加载所有的数据库......
当你说Hibernate没有填充cat Set时,恕我直言,只是因为调试器中的 该集合最初不是空的也不是空的,因此调试器不会问hibernate发出查询。但如果您在代码中询问了猫的列表,那么您就可以正确使用它。答案 1 :(得分:1)
经过一天的激烈努力,我得到了它。问题发生在LEFT_OUTER_JOIN
。用INNER_JOIN
替换它,我的所有嵌套集合都被完全填满。有关更详细的说明,请参阅https://hibernate.atlassian.net/browse/HHH-2049