我们正在将Spring Data存储库与Hibernate 5.x一起使用
我们有一个层次很深的实体图。 映射如下所示:
@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()调用,该调用在从分离的对象复制状态更改之前从db获取对象图。
我有两个问题:
为什么休眠无法像使用fetchgraph时那样将这些语句加入一个大选择?
当我从关系中删除所有级联选项时,它仍然会导致多个选择,但只会更新顶部的FooBar实体的属性。为什么即使没有级联合并,hibernate仍然在合并期间获取所有已加载的子实体?
谢谢
答案 0 :(得分:1)
如this article中所述,您可以使用session.update
而不是合并来解决此问题。
Session session = entityManager.unwrap( Session.class );
for ( Post post: posts ) {
session.update( post );
}