Мы используем репозитории 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 запроса при выборке ленивых ассоциаций.
После вызова службы для загрузки графа сущности транзакция закончилась, и сущность отсоединилась.
При последующем вызове save для объекта FooBar это вызывает несколько операторов выбора. Каждый выбирает одну из дочерних сущностей.
Я знаю, что это происходит из вызова entitymanager merge (), который выбирает граф объектов из БД перед копированием изменений состояния из отсоединенных объектов.
У меня два вопроса:
Почему hibernate не может объединить эти операторы в один большой выбор, например, что происходит при использовании fetchgraph?
Когда я удаляю все каскадные опции из отношений, он все равно вызывает множественный выбор, но будут обновляться только атрибуты вершины, сущности FooBar. Почему hibernate по-прежнему извлекает все загруженные дочерние объекты во время объединения даже без каскадного объединения?
Спасибо