查询懒惰时,Hibernate获取急切关联

时间:2014-08-06 07:27:06

标签: hibernate hql

我有一个父子关系的常见情况,如:

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调用?

2 个答案:

答案 0 :(得分:1)

通过指定FetchType.EAGER,您已经对Hibernate说过,每次加载父对象时,您都希望它加载这些子对象。如果您不希望发生这种情况,则无法指定Eager fetch类型。

Hibernate不够聪明,知道当你查询Parent时,你只需要lazyChild。它只知道你已经向Parent对象发出了请求,因此它需要加载急切的获取子项。

如果您不熟悉Hibernate,可能会发现我的教程here很有帮助。

答案 1 :(得分:0)

我不确定我明白你想做什么。 但是,如果您不希望加载集合childrenOnechildrenTwo,则应该使用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;