Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does @ElementCollection imply orphanRemoval?

According to this post Difference between @OneToMany and @ElementCollection? I should prefer @ElementCollection for embeddable types and @OneToMany for entities. But using @OneToMany I can additionaly set option orphanRemoval=true. How can I do this with @ElementCollection? It it implied?

like image 430
k13i Avatar asked Oct 18 '25 14:10

k13i


1 Answers

It is implied. Removing the owning entity would also remove all data on the @ElementCollection. Setting the Collection to null or changing elements in the Collection would cause an update if Session isn't already closed.

The official documentation here says this:

2.8.1. Collections as a value type

Value and embeddable type collections have a similar behavior as simple value types because they are automatically persisted when referenced by a persistent object and automatically deleted when unreferenced. If a collection is passed from one persistent object to another, its elements might be moved from one table to another.
...
For collections of value types, JPA 2.0 defines the @ElementCollection annotation. The lifecycle of the value-type collection is entirely controlled by its owning entity.

I ran these three tests to test it out:

  @Test
  public void selectStudentAndSetBooksCollectionToNull() {
    Student student = studentDao.getById(3L);
    List<String> books = student.getBooks();

    books.forEach(System.out::println);

    student.setBooks(null);

    em.flush(); // delete from student_book where student_id = ?
  }

  @Test
  public void selectStudentAndAddBookInCollection() {
    Student student = studentDao.getById(3L);
    List<String> books = student.getBooks();

    books.add("PHP Book");

    books.forEach(System.out::println);

    em.flush(); // insert into student_book(student_id, book) values(?, ?)
  }

  @Test
  public void selectStudentAndChangeCollection() {
    Student student = studentDao.getById(3L);
    List<String> newBooks = new ArrayList<>();

    newBooks.add("Rocket Engineering");

    newBooks.forEach(System.out::println);

    student.setBooks(newBooks);

    em.flush(); // delete from student_book where student_id = ?
    // insert into student_book(student_id, book) values(?, ?)
  } 

This is the Student class:

@Entity
@Table(name = "student")
public class Student {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "student_id", nullable = false, insertable = false, updatable = false)
  private Long id;

  @Column(name = "name", nullable = false)
  private String name;

  @ElementCollection
  @CollectionTable(
      name = "student_books",
      joinColumns = @JoinColumn(name = "student_id", referencedColumnName = "student_id"))
  @Column(name = "book")
  private List<String> books = new ArrayList<>();

  // Getters & Setters

}
like image 139
Yoshua Nahar Avatar answered Oct 21 '25 02:10

Yoshua Nahar