首页 > 解决方案 > 如何在休眠中仅删除@OneToOne双向映射的一侧

问题描述

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

面试实体

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

我正在考虑分配mappedByinterview实体,但是,我不确定这是否是解决方案,而且我也有保留,因为我的interview实体是在创建实体之后创建的applicant

标签: javaspringhibernatespring-mvc

解决方案


您应该只在实体上使用cascade = ...and (在您的情况下)。在关联的两侧使用级联没有意义(对于任何关系,不仅仅是一对一)。想想级联的作用,以及当你尝试创建一个新的. 表示实体需要创建一个如果面试对象被赋予一个申请人字段。一旦创建了申请者,它就会看到申请者实体有,这意味着它需要保留它拥有的任何字段,因此它会再次尝试创建一个,这没有意义,因为您已经创建了面试。orphanRemoval = ...ApplicantInterviewCascadeType.PERSISTInterviewApplicantCascadeType.ALLInterviewInterview

我猜测它为什么要删除Applicant是因为你orphanRemoval在双方都有。HibernateInterview认为因为它有orphanRemoval它是关联的父端,所以一旦你删除Interview它就认为Applicant不再需要它,因此也删除了该记录。

Hibernate 文档在这里说明了很多:

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

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


推荐阅读