我有一个父子关系的常见情况,如:
class Parent {
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
List<ChildOne> childrenOne;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
List<ChildTwo> childrenTwo;
@OneToMany
List<LazyChild> lazyChildren;
@Id
Long id;
}
然后我有HQL查询,如:
select lazyChild from Parent p
join p.lazyChildren lazyChild
where p.id = ? and lazyChild.mnemonic='AAA'
当我执行它时,我得到了LazyChild对象,这就是我想要的。但是hibernate也初始化了所有热切定义的集合,这是我不想要的。 hibernate对获取热切关联进行单独调用并不直观。我通过切换到显示SQL查询来看到它。
如何避免不必要的SQL调用?
答案 0 :(得分:1)
通过指定FetchType.EAGER
,您已经对Hibernate说过,每次加载父对象时,您都希望它加载这些子对象。如果您不希望发生这种情况,则无法指定Eager fetch类型。
Hibernate不够聪明,知道当你查询Parent
时,你只需要lazyChild。它只知道你已经向Parent
对象发出了请求,因此它需要加载急切的获取子项。
如果您不熟悉Hibernate,可能会发现我的教程here很有帮助。
答案 1 :(得分:0)
我不确定我明白你想做什么。
但是,如果您不希望加载集合childrenOne
和childrenTwo
,则应该使用FetchType.LAZY
声明它们。
在我看来,你不是在查询正确的实体,如果你只想要一个LazyChild
的列表,那么你的HQL应该是这样的:
from LazyChild child
where child.parent.id = ? and child.mnemonic='AAA'
假设您在LazyChild
实体中映射了父级:
@ManyToOne //(fetch=FetchType.LAZY) if you don't need to have the parent loaded
@JoinColumn(name = "parent_id")
private Parent parent;