【发布时间】:2019-02-16 16:42:25
【问题描述】:
我们在 Hibernate 5.x 中使用 Spring Data 存储库
我们有一个层次很深的实体图。 映射如下所示:
@Entity
public class FooBar {
@OneToMany(mappedBy = "fooBar", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Foo> chassis = new HashSet<>(0);
...
}
@Entity
public class Foo {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "foobar_id")
private FooBar fooBar;
@OneToMany(mappedBy = "foo", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Bar> chassis = new HashSet<>(0);
...
}
@Entity
public class Bar {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "foo_id")
private FooBar foo;
...
}
如您所见,FooBar 实体有一组 Foo 实体。每个 Foo 实体包含更多的 Bar 实体等等。
我们使用 Fetchgraph 功能在运行时加载具有我们需要的关系的 FooBar 实体,以避免在获取惰性关联时出现 n+1 查询问题。 在调用加载实体图的服务之后,事务已经结束并且实体被分离。
稍后在 FooBar 实体上调用 save 时,这会导致多个 select 语句。每个都获取一个子实体。
我知道这来自 entitymanager merge() 调用,该调用在从分离的对象复制状态更改之前从数据库中获取对象图。
我有两个问题:
为什么 hibernate 不能像使用 fetchgraph 时那样将这些语句加入到一个大选择中?
当我从关系中删除所有级联选项时,它仍然会导致多次选择,但只会更新顶部 FooBar 实体的属性。为什么即使没有级联合并,hibernate 在合并期间仍会获取所有加载的子实体?
谢谢
【问题讨论】:
标签: java hibernate jpa merge orm