Я определил два класса: «Родительский и детский». Родитель может иметь список детей.Однонаправленное преобразование «один ко многим» в Hibernate генерирует избыточные обновления.
@Entity
public class Parent {
@Id
@GeneratedValue(...)
@SequenceGenerator(...)
private long id;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "parent_id", referencedColumnName = "id", nullable = false)
private List<Child> children;
public Parent() {
children = new ArrayList<Child>();
}
public void addChild(Child child) { children.add(child); }
}
@Entity
public class Child {
@Id
@GeneratedValue(...)
@SequenceGenerator(...)
private long id;
// The "Child" table in the db also has a not-null "parent_id" column.
}
Если добавить кучу детей в список и сохраняться родитель все работает, как ожидалось: Hibernate получает значения последовательности, сохраняет родителя и затем сохраняет все дети.
Однако, выполнив все это, он обновит все дочерние элементы, установив «parent_id» на значение, которое уже было установлено во вставке!
Сгенерированный SQL выглядит следующим образом:
insert into PARENT (id) values (1)
insert into CHILD (parent_id, id) values (1, 1)
insert into CHILD (parent_id, id) values (1, 2)
insert into CHILD (parent_id, id) values (1, 3)
update CHILD set parent_id = 1 WHERE id = 1
update CHILD set parent_id = 1 WHERE id = 2
update CHILD set parent_id = 1 WHERE id = 3
Если я это объединение двунаправленным он работает отлично, но тогда мне нужна ссылка на родитель в моем классе ребенка и что-то я хочу, чтобы избежать.
Хранилище представляет собой хранилище Spring Data JPA:
public interface ParentRepository extends PagingAndSortingRepository<Parent, Long> {}
The (упрощенный) код, который создает и сохраняет объекты:
Parent parent = new Parent();
parent.addChild(new Child());
parent.addChild(new Child());
repo.save(parent);
Любые предложения?
@chsdk, чем дополнительный код вам нужно? Если это помогает, я использую репозиторий Spring Data JPA, на который я вызываю save (parent). Как родитель, так и дети полностью неизменяемы после создания с помощью строителя. –
Попробуйте добавить 'mappedBy' атрибут к вашему сопоставлению следующим образом:' @OneToMany (mappedBy = "parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 'где parent должно быть именем поля Parent в Child класс. –
@chsdk, как я уже упоминал в вопросе, у меня нет ссылки на родителя в моем ребенке. Это однонаправленная ассоциация. –