Search code examples
javahibernatejpaone-to-manyhibernate-mapping

Unidirectional @OnetoMany mapping deletes all relationships and re-adds remaining ones rather than removing the specific one


Given the following code

public class Course {
    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Review> reviews = new ArrayList<>();
}

public class Review {
    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String rating;
    private String description;
}

Saved course with 2 reviews.

If I try to remove one review from course.

course.getReviews().remove(0);

Hibernate fires following queries.

delete from course_reviews where course_id=? 
binding parameter [1] as [BIGINT] - [1]
insert into course_reviews (course_id, reviews_id) values (?, ?) 
binding parameter [1] as [BIGINT] - [1]
binding parameter [2] as [BIGINT] - [3]

Notice that it deletes all the relationships first and then inserts the remaining. Why this behavior? Why couldn't it be more specific and delete just that one record storing the relationship.


Solution

  • Not sure if this is due to bag semantics(because you use a List rather than Set for reviews) or just because Hibernate sometimes does so called "collection recreations". Try using a Set.