@OneToOne关联不能在查询中急切加载

时间:2013-05-27 09:18:20

标签: java hibernate jpa ejb-3.0

我有以下实体:

//The class Entity is a @MappedSuperclass with id, audit fields, equals and so on.
@Entity
public class Foo extends Entity {
    @OneToMany(mappedBy = "foo", cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Bar> bars = new HashSet<Bar>; // + getter/setter

    // ... other properties
}

@Entity
public class Bar extends Entity {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "foo_id")
    private Foo foo; // +getter/setter

    @OneToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "baz_id", nullable = false)
    private Baz baz; // + getter/setter

    // ... other properties
}

@Entity
public class Baz extends Entity {
    @OneToOne(mappedBy = "baz", fetch = FetchType.LAZY, optional = false)
    private Bar bar; // + getter/setter

    // ... other properties
}

现在如果我使用以下内容加载Bar,一切都很顺利(即只有一个查询被发送到数据库):

SELECT bar FROM Bar bar LEFT JOIN FETCH bar.baz WHERE bar.id = :barId

但是,如果我执行以下任一操作,则会为每个SELECT创建一个新的Baz以获取关联的Bar对象:

SELECT f FROM Foo f LEFT JOIN FETCH f.bars bar LEFT JOIN FETCH bar.baz WHERE f.id = :fooId
SELECT f FROM Foo f LEFT JOIN FETCH f.bars bar LEFT JOIN FETCH bar.baz baz LEFT JOIN FETCH baz.bar WHERE f.id = :fooId

输出结果为:

10:52:08,622 INFO  [STDOUT] Hibernate: select ... from Foo ...
10:52:08,698 INFO  [STDOUT] Hibernate: select ... from Bar where baz_id=?
10:52:08,711 INFO  [STDOUT] Hibernate: select ... from Bar where baz_id=?
... and so on

现在,我从this answer了解到@OneToOne有延迟加载的问题,所以我按照他们的建议添加了可选= false(这似乎对我没什么用)。

我也尝试过来自this blogpost的建议3,但这似乎根本没有效果..

有关如何急切获取对象图以避免SELECT n + 1问题的任何建议吗?

我在JBoss 4.2服务器上使用EJB 3(JPA 1)和Hibernate 3.2.4.sp1。

注意:这有点类似于我的previous questions之一。不同之处在于Baz有一个回复Bar的引用,这似乎是个问题。

1 个答案:

答案 0 :(得分:0)

通过删除Baz到Bar的后引用,我能够解决这个问题。我没有找到根本原因,或者没有额外选择而急切地加载对象的方法。