如何在更新之前强制Hibernate删除孤立

时间:2017-09-14 08:38:39

标签: java hibernate jpa constraints unique

我们说我有以下模型结构:

@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;
    }
}

目前我group1 AnnotationOption opt1 opt2opt3

opt1

然后我想用一个选项 CONSTRAINT "UQ_ANNOTATION_OPTION_name_annotation_group_id" UNIQUE (annotation_option_name, annotation_group_id)

替换所有选项

enter image description here

另外我在数据库中有约束:

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.

这一次开火了:

{{1}}

实际上,假设hibernate在更新后删除了孤儿。

你能提出解决问题的建议吗?

2 个答案:

答案 0 :(得分:5)

这个例子中有很多错误:

  1. 获取@OneToMany集合的EAGER为almost always a bad idea
  2. 单向收集也不好,请使用bidirectional one
  3. 如果您收到此异常,则很可能清除了所有元素并重新添加了要保留的元素。
  4. 解决这个问题的最佳方法是将现有的子集与传入的子集明确合并,以便:

    1. 新的子实体正被添加到集合中。
    2. 删除不再需要的子实体。
    3. 与业务密钥(annotation_group_namestudy_id)匹配的子实体将使用传入数据进行更新。
    4. 有关详细信息,请查看High-Performance Java Persistence

答案 1 :(得分:1)

根据Hibernate documentation hibernate按以下顺序执行以保留外键约束:

  1. 按照执行顺序插入
  2. 更新
  3. 删除集合元素
  4. 插入集合元素
  5. 按照执行顺序删除
  6. 为了您的特殊需要,您应该手动刷新事务以强制在数据库中删除。