我在两个单独的实体中有两列


  面试实体


@OneToOne(cascade=CascadeType.PERSIST, orphanRemoval = true)
@JoinColumn(name = "applicant_id", nullable=false)
private Applicant applicant_id;



  申请人实体


@OneToOne(mappedBy="applicant_id", cascade = CascadeType.ALL, orphanRemoval = true)
private Interview interview_id;


问题是,如何正确映射它,以便我可以运行service.deleteInterview();并仅删除interview实体记录?

如果我使用cascadeType.all删除applicant实体。我尝试将其更改为持久,然后出现500错误,提示如果调用该函数,将重新创建实体。

添加orphan removal=true最终出现此异常org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null];

我当时正在考虑将mappedBy分配给interview实体,但是,我不确定这是否是解决方案,并且由于在创建interview实体后创建了applicant实体,所以我也有所保留。

最佳答案

您只能在父实体(在您的情况下为cascade = ...)上使用orphanRemoval = ...Applicant。在关联的两端都使用级联是没有意义的(对于任何关系,而不仅仅是一对一的关系)。考虑级联的作用,以及尝试创建新的Interview时会发生什么。 CascadeType.PERSIST说,如果面试对象被赋予了申请人字段,则Interview实体需要创建一个Applicant。创建申请人后,它会看到申请人实体具有CascadeType.ALL,这意味着它需要保留其拥有的任何Interview字段,因此它将再次尝试创建Interview,这没有任何意义。因为您已经创建了采访。

我之所以会删除Applicant的猜测是因为两边都有orphanRemoval。 Hibernate查看Interview并认为由于它具有orphanRemoval,因此它是关联的父级,因此,一旦删除Interview,它就会认为不再需要Applicant,因此也删除了该记录。

Hibernate文档指出了许多here


  ...只有关联的父级才有意义将其实体状态转换级联到子级。


浏览该指南中的一些示例,以了解它们如何在OneToOne关系中使用级联。

10-08 13:40