【发布时间】:2015-06-26 08:26:00
【问题描述】:
我有两个实体 Business,它们由 Departments
列表组成@Entity
@Table(name = "Business")
public class Business implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id")
private Long id;
@OneToMany(mappedBy = "business",
cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Department> departments;
@OneToMany(mappedBy = "business", orphanRemoval = true,
cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private List<Process> processs;
@ManyToMany
private List<Competence> competences;
}
@Entity
@Table(name = "Department")
public class Department implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "father",
cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Department> departments;
}
当我尝试删除一个业务实例时,我得到一个 Mysql 异常
无法删除或更新父行:外键约束失败(evac_java.Department, CONSTRAINT FK_Department_Business FOREIGN KEY (Business) REFERENCES Business (Id)): HY000 - 空
这意味着我无法删除业务实例,因为它有与之关联的部门,但部门本身不能存在,因此我想在删除业务实例时删除所有业务部门。我以为我可以通过将 cascade = CascadeType.REMOVE 添加到业务实体中的 @OneToMany 注释来实现这一点,但它不起作用。
我在网上进行了搜索,在 stackoverflow 上发现了很多与此类似的问题,但它们都提出了相同的建议:add cascade = CascadeType.REMOVE 或 CascadeType.ALL
所以我想知道我是否遗漏了一些东西。
我正在使用 Glassfish 4.1 和 EclipseLink
我试过了
@OneToMany(mappedBy = "business", orphanRemoval = true)
private List<Department> departments;
在业务实体上,但它也不起作用
这是我用来删除在抽象类中声明的实体的方法
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
【问题讨论】:
-
我认为你应该在你想要删除项目的列表中添加 orphanremoval =true 头
-
我确实考虑过这个选项,但是对于 CascadeType.REMOVE 来说这不是多余的,而且更激进吗?在这种情况下应该可以,但是如果我不需要移除孩子怎么办?
-
如果是onetomany关系则意味着没有父类就不能存在子级。所以如果您删除父类则意味着您必须删除相关项或更新相关列null
-
您是否尝试了
orphanRemoval和cascade选项?孤立删除只是说删除孤立的行(这是您想要的行为),而级联选项只是说在删除拥有方时触发删除。除了这里定义的之外,您还定义了任何额外的 FK 吗?生成的 DDL 是什么样的,JPA 实现是什么?
标签: java jpa eclipselink java-ee-7