Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force Hibernate to remove orphans before update

Let's say I have following model structure:

@Entity
@Table(....)
public class AnnotationGroup{
    ...
    private List<AnnotationOption> options;


    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinColumn(name = "annotation_group_id", nullable = false)
    public List<AnnotationOption> getOptions() {
        return options;
    }
}

@Entity
@Table(...)
public class AnnotationOption {

    private Long id;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Override
    public Long getId() {
        return id;
    }
}

At the moment I have group1 with AnnotationOptions opt1 opt2 and opt3

Then I want to replace all option with only one option opt1

enter image description here

Additionally I have constraint in database:

    CONSTRAINT "UQ_ANNOTATION_OPTION_name_annotation_group_id" UNIQUE (annotation_option_name, annotation_group_id)

And this one fires:

Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "UQ_ANNOTATION_OPTION_name_annotation_group_id"
  Detail: Key (name, annotation_group_id)=(opt1, 3) already exists.

Actually isuue that hibernate removes orphans after update.

Can you suggest something t resolve issue?

like image 768
gstackoverflow Avatar asked Mar 08 '23 02:03

gstackoverflow


1 Answers

There are so many things that are wrong in this example:

  1. EAGER fetching on the @OneToManycollection is almost always a bad idea.
  2. Unidirectional collections are also bad, use the bidirectional one.
  3. If you get this exception, most likely you cleared all the elements and re-added back the ones that you want to be retained.

The best way to fix it is to explicitly merge the existing set of children with the incoming ones so that:

  1. New child entities are being added to the collection.
  2. The child entities that are no longer needed are removed.
  3. The child entities matching the business key (annotation_group_name, study_id) are updated with the incoming data.
like image 170
Vlad Mihalcea Avatar answered Mar 16 '23 15:03

Vlad Mihalcea