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?

- 4,011
- 3
- 35
- 63
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
}

- 6,105
- 3
- 36
- 59

- 1,304
- 11
- 28
-
But that's not orphanRemoval is all about. Of course if you remove parent, children will be removed in a cascade way, but what if you just lose reference (e.g. by setting it to null) to the child, so that it's not available anymore? – k13i Sep 26 '17 at 13:24
-
3Yes, the `@ElementCollection` field implicitly has `Cascasde.ALL` + `orphanRemoval = true` – Yoshua Nahar Sep 28 '17 at 17:38
-
Using Hibernate 5.0.12.Final a constraint is created with no delete cascade – lrkwz Sep 22 '22 at 09:45