How to force Hibernate to remove orphans before update

落花浮王杯 提交于 2020-01-19 14:53:26

问题


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

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?


回答1:


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.

For more details, check out High-Performance Java Persistence.




回答2:


According to Hibernate documentation hibernate perform in the following order to preserve foreign-key constraint:

  1. Inserts, in the order they were performed
  2. Updates
  3. Deletion of collection elements
  4. Insertion of collection elements
  5. Deletes, in the order they were performed

For your special need you should manually flush the transaction to force the deletion in database before.



来源:https://stackoverflow.com/questions/46214322/how-to-force-hibernate-to-remove-orphans-before-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!