我在两个单独的实体中有两列
面试实体
@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
关系中使用级联。