带有CascadeType.ALL的JPA @ManyToOne

问题

我想我错过了解@ManyToOne关系中的级联的意义。

案子:

public class User {

   @OneToMany(fetch = FetchType.EAGER)
   protected Set<Address> userAddresses;

}

public class Address {

   @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
   protected User addressOwner;

}

cascade = CascadeType.ALL是什么意思?例如,如果我从数据库中删除某个地址,那么我添加cascade = CascadeType.ALL对我的数据(我猜的用户)的影响是怎么回事?


#1 热门回答(254 赞)

CascadeType.ALL的含义是持久性将传播(级联)allEntityManager操作(PERSIST, REMOVE, REFRESH, MERGE, DETACH)到相关实体。

在你的情况下似乎是一个坏主意,因为删除anAddress将导致删除相关的User。由于用户可以拥有多个地址,因此其他地址将成为孤儿。然而,相反的情况(注释User)是有意义的 - 如果地址仅属于单个用户,则如果删除此用户,则传播删除属于用户的所有地址是安全的。

顺便说一句:你可能希望向yourUser添加amappedBy="addressOwner"属性,以向持久性提供程序发出信号,表明连接列应位于ADDRESS表中。


#2 热门回答(35 赞)

See here来自OpenJPA docs.CascadeType.ALL的一个例子,它将执行所有操作。

引用:

CascadeType.PERSIST:持久化实体时,也会保留此字段中保存的实体。我们建议自由应用此级联规则,因为如果EntityManager在刷新期间找到引用新实体的字段,并且该字段不使用CascadeType.PERSIST,则这是一个错误。 CascadeType.REMOVE:删除实体时,还要删除此字段中包含的实体。 CascadeType.REFRESH:刷新实体时,还刷新此字段中保存的实体。 CascadeType.MERGE:合并实体状态时,还合并此字段中保存的实体。

塞巴斯蒂安


#3 热门回答(15 赞)

From the EJB3.0 Specification

级联注释元素的使用可用于将操作的效果传播到关联实体。级联功能最常用于父子关系。如果X是托管实体,则删除操作会导致其被删除。如果从X到这些其他实体的关系使用cascade = REMOVE或cascade = ALL注释元素值进行注释,则删除操作将级联到X引用的实体。

因此,简而言之,使用4853330定义的实体关系将确保将父节点上发生的所有持久性事件(如持久性,刷新,合并和删除)传递给子节点。定义otherCascadeTypeoptions为开发人员提供了对实体关联如何处理持久性的更细粒度控制。

例如,如果我有一个包含页面列表的对象书,我在此列表中添加一个页面对象。如果定义Book和Page之间关联的@OneToManyanannotation标记为CascadeType.All,则持久化Book将导致Page也被持久化到数据库。