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



我有以下实体:

//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与以下,一切都很好(即只有一个查询被发送到DB):

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

但是,如果我执行以下任何一项操作,则为每个Baz创建一个新的SELECT以获得相关的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

现在,我从这个答案中了解到@OneToOne有延迟加载的问题,所以我听从了他们的建议并添加了optional = false(这似乎对我没有多大帮助)。

我也试过这篇博文中的建议3,但似乎一点效果也没有。

有什么建议如何急切地获取对象图,以避免SELECT n+1问题?

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

注意:这有点类似于我之前的一个问题。不同的是,这里的Baz有一个引用回到Bar,这似乎是问题。

我能够解决这个问题,通过删除从Baz到Bar的反向引用。我没有找到潜在的原因,也没有找到一种无需额外选择即可急切加载对象的方法。

最新更新