JPA OneToMany不删除孩子
我有一个父和@OneToMany
之间简单的@OneToMany
映射的问题。 一切正常,只有当我从集合中删除它们时,子logging才会被删除。
父母:
@Entity public class Parent { @Id @Column(name = "ID") private Long id; @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "parent") private Set<Child> childs = new HashSet<Child>(); ... }
小孩:
@Entity public class Child { @Id @Column(name = "ID") private Long id; @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name="PARENTID", nullable = false) private Parent parent; ... }
如果我现在从子集Set中删除子元素,它不会从数据库中删除。 我试图取消child.parent
引用,但也没有工作。
实体用于Web应用程序,删除是作为Ajax请求的一部分发生的。 当按下保存button时,我没有删除子项列表,所以我不能隐式删除它们。
JPA的行为是正确的( 按照规范的含义):对象不会被简单地删除,因为你已经从OneToMany集合中删除了它们。 有特定于供应商的扩展可以这样做,但本机JPA不适合它。
部分原因是因为JPA实际上并不知道是否应该删除从集合中删除的东西。 在对象build模方面,这是组合和“聚合*”之间的区别。
在构成上 ,没有父母,子女实体就没有存在。 房子和房间之间就是一个典型的例子。 删除房子和房间也去。
聚合是一种更松散的联系,并以课程和学生为代表。 删除课程,学生仍然存在(可能在其他课程)。
因此,您需要使用特定于供应商的扩展来强制执行此行为(如果可用),或者显式删除子级并将其从父级集合中移除。
我知道:
- hibernate :级联delete_orphan。 见10.11。 传递持久性 ; 和
- EclipseLink :将其称为“私人所有权”。 请参阅如何使用@PrivateOwned注释 。
除了Cletus的回答,2010年12月的最后一个JPA 2.0在@OneToMany
注释中引入了orphanRemoval
属性。 欲了解更多详情,请参阅此博客条目
请注意,由于规范相对较新,并非所有JPA 1提供者都有最终的JPA 2实现。 例如, Hibernate 3.5.0-Beta-2版本还不支持这个属性。
你可以试试这个:
@OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true)
。
正如所解释的那样,我不能用JPA来做我想做的事情,所以我使用了hibernate.cascade注释,现在父类中的相关代码如下所示:
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy = "parent") @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE, org.hibernate.annotations.CascadeType.MERGE, org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.DELETE_ORPHAN}) private Set<Child> childs = new HashSet<Child>();
我不能简单地使用'ALL',因为这也会删除父项。
这里级联,在删除的情况下,意味着如果你删除父母的孩子被删除。 不是这个协会。 如果您使用Hibernate作为您的JPA提供程序,则可以使用hibernate特定的级联来完成此操作。
@Entity class Employee { @OneToOne(orphanRemoval=true) private Address address; }
看到这里 。
你可以试试这个:
@OneToOne(cascade = CascadeType.REFRESH)
要么
@OneToMany(cascade = CascadeType.REFRESH)