У меня есть 3 таблицы базы данных (books
, authors
, books_authors
), и они представлены 2 сущностями (Book
, Author
) с однонаправленным отношением «многие ко многим». Каждый класс сущностей имеет свои Repository
(расширяющий JpaRepository
) и Service
класс.
Цель состоит в том, чтобы иметь возможность сохранить новый или существующий Book
с новым или существующим Author
( s) то есть сохранение детей вместе с родителем.
При попытке сохранить новый Book
с существующими Author
, используя единственный метод сохранения, предоставленный JpaRepository
(save
), Я получаю исключение о том, что
отдельная сущность передана для сохранения
Поскольку Book
является новым, метод save
будет использовать persist
вместо merge
и persist
каскадно (из-за CascadeType.PERSIST
) к детям, которые уже существуют. Есть ли способ каскадного сохранения разумным способом, когда он использует persist
и merge
на основе текущего Entity
вместо того, что было каскадно от родительского? Я думаю, что это общая проблема, поэтому должно быть хорошо разработанное решение.
Из обсуждений, которые мне удалось найти и понять, удаление CascadeType.PERSIST
решило бы проблему с отсоединенной сущностью, но это не дать вам возможность спасти детей вместе с родителем. Кроме того, save
можно заменить на merge
(требуется использование EntityManager
), но это заставит задуматься, зачем вообще беспокоиться о save
, и, основываясь на обсуждениях, которые я прочитал, это может не быть решением.
books
идентификатор, имя
authors
идентификатор, имя
books_authors
id, book_id, author_id
@Entity
@Table(name = "books")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(insertable = false, name = "id", nullable = false)
private Long id;
@ManyToMany(
fetch = FetchType.EAGER,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.REFRESH,
CascadeType.DETACH
})
@JoinTable(
name = "books_authors",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "author_id"))
private Set < Author > authors;
}
@Entity
@Table(name = "authors")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(insertable = false, name = "id", nullable = false)
private Long id;
@Column(name = "name", nullable = false)
private String name;
}