Anonymous
Автоматически удалять дочерний элемент из родительского
Сообщение
Anonymous » 16 апр 2024, 10:06
Код: Выделить всё
@Entity
public class Book implements Serializable {
@Id
private Long bookId;
private String title;
@ManyToOne
@JoinColumn(name = "author_id")
private Author author;
// getter and setter removed for brevity
}
@Entity
public class Author implements Serializable {
@Id
@Column(name = "author_id")
private Long authorId;
private String name;
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Set books = new HashSet();
// getter and setter removed for brevity
public void addBook(Book book) {
getBooks().add(book);
book.setAuthor(this);
}
}
Рассмотрим следующий тест
Код: Выделить всё
@Test
public void manyToOneAndRemove() {
System.out.println("Test");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Author author = new Author();
author.setAuthorId(1L);
author.setName("Deepak Kumar");
em.merge(author);
em.flush();
Book book = new Book();
book.setBookId(11L);
book.setTitle("Welcome to CSS");
em.merge(book);
em.flush();
Author author1 = em.find(Author.class, 1L);
author1.addBook(book);
em.merge(author1);
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
Author author2 = em.find(Author.class, 1L);
System.out.println("Load 1:");
author2.getBooks().forEach(b -> {
System.out.printf("Book: (%s,%s)", b.getBookId(), b.getTitle());
System.out.println();
});
Book aBook = em.find(Book.class, 11L);
em.remove(aBook);
em.flush();
Author author3 = em.find(Author.class, 1L);
System.out.println("Load 2:");
author3.getBooks().forEach(b -> {
System.out.printf("Book: (%s,%s)", b.getBookId(), b.getTitle());
System.out.println();
});
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
Author author4 = em.find(Author.class, 1L);
System.out.println("Load 3:");
author4.getBooks().forEach(b -> {
System.out.printf("Book: (%s,%s)", b.getBookId(), b.getTitle());
System.out.println();
});
em.getTransaction().commit();
em.close();
}
Выход будет
Код: Выделить всё
Test
Load 1:
Book: (11,Welcome to CSS)
Load 2:
Book: (11,Welcome to CSS)
Load 3:
Book: (11,Welcome to CSS)
Краткое объяснение:
Сохраните автора
Сохраните книгу и добавить книгу в книги автора.
Загрузить автора в новой транзакции, чтобы убедиться, что книга правильно связана с автором.
Удалить книгу. напрямую.
Загрузите автора, чтобы книга была автоматически удалена из книг автора.
Шаг 5. неверно.
Как видите, книга не удаляется из родительского объекта. У автора сохранилась ссылка на книгу. Насколько я понимаю, книга должна автоматически удаляться из коллекции в сущности автора?!
Подробнее здесь:
https://stackoverflow.com/questions/783 ... its-parent
1713251177
Anonymous
[code]@Entity public class Book implements Serializable { @Id private Long bookId; private String title; @ManyToOne @JoinColumn(name = "author_id") private Author author; // getter and setter removed for brevity } @Entity public class Author implements Serializable { @Id @Column(name = "author_id") private Long authorId; private String name; @OneToMany(mappedBy = "author", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) private Set books = new HashSet(); // getter and setter removed for brevity public void addBook(Book book) { getBooks().add(book); book.setAuthor(this); } } [/code] Рассмотрим следующий тест [code]@Test public void manyToOneAndRemove() { System.out.println("Test"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); Author author = new Author(); author.setAuthorId(1L); author.setName("Deepak Kumar"); em.merge(author); em.flush(); Book book = new Book(); book.setBookId(11L); book.setTitle("Welcome to CSS"); em.merge(book); em.flush(); Author author1 = em.find(Author.class, 1L); author1.addBook(book); em.merge(author1); em.getTransaction().commit(); em.close(); em = emf.createEntityManager(); em.getTransaction().begin(); Author author2 = em.find(Author.class, 1L); System.out.println("Load 1:"); author2.getBooks().forEach(b -> { System.out.printf("Book: (%s,%s)", b.getBookId(), b.getTitle()); System.out.println(); }); Book aBook = em.find(Book.class, 11L); em.remove(aBook); em.flush(); Author author3 = em.find(Author.class, 1L); System.out.println("Load 2:"); author3.getBooks().forEach(b -> { System.out.printf("Book: (%s,%s)", b.getBookId(), b.getTitle()); System.out.println(); }); em.getTransaction().commit(); em.close(); em = emf.createEntityManager(); em.getTransaction().begin(); Author author4 = em.find(Author.class, 1L); System.out.println("Load 3:"); author4.getBooks().forEach(b -> { System.out.printf("Book: (%s,%s)", b.getBookId(), b.getTitle()); System.out.println(); }); em.getTransaction().commit(); em.close(); } [/code] Выход будет [code]Test Load 1: Book: (11,Welcome to CSS) Load 2: Book: (11,Welcome to CSS) Load 3: Book: (11,Welcome to CSS) [/code] Краткое объяснение: [list] [*]Сохраните автора [*]Сохраните книгу и добавить книгу в книги автора. [*]Загрузить автора в новой транзакции, чтобы убедиться, что книга правильно связана с автором. [*]Удалить книгу. напрямую. [*]Загрузите автора, чтобы книга была автоматически удалена из книг автора. [/list] Шаг 5. неверно. Как видите, книга не удаляется из родительского объекта. У автора сохранилась ссылка на книгу. Насколько я понимаю, книга должна автоматически удаляться из коллекции в сущности автора?! Подробнее здесь: [url]https://stackoverflow.com/questions/78332698/automatically-remove-a-child-from-its-parent[/url]