对于@ManyToOne JPA关联,CascadeType.ALL的含义是什么?

for*_*has 193 java jpa cascade one-to-many many-to-one

我想我误解了在@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;

}
Run Code Online (Sandbox Code Playgroud)

这是什么意思cascade = CascadeType.ALL?例如,如果我从数据库中删除某个地址,我添加的事实如何cascade = CascadeType.ALL影响我的数据(User我猜)?

kos*_*tja 324

意思CascadeType.ALL是持久性将所有EntityManager操作(PERSIST, REMOVE, REFRESH, MERGE, DETACH)传播(级联)到相关实体.

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

顺便说一句:您可能希望向您添加一个mappedBy="addressOwner"属性,User以向持久性提供程序发出连接列应位于ADDRESS表中的信号.

  • +1对于我遇到过的最好和最简短的解释. (48认同)
  • 虽然在@OneToMany方面有CascadeType.ALL可能会很好. (4认同)

seb*_*ner 42

请参阅此处以获取OpenJPA文档中的示例.CascadeType.ALL意味着它会做所有的行动.

引用:

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

CascadeType.REMOVE:删除实体时,还要删除此字段中保存的实体.

CascadeType.REFRESH:刷新实体时,还刷新此字段中保存的实体.

CascadeType.MERGE:合并实体状态时,还合并此字段中保存的实体.

塞巴斯蒂安

  • JPA中的新功能,这些信息很有用但是这里的Detach呢? (4认同)

Vla*_*cea 23

正如我在本文和我的书" 高性能Java持久性"中所解释的那样,您永远不应该使用CascadeType.ALL,@ManyToOne因为实体状态转换应该从Parent实体传播到Child实体.

@ManyToOne侧始终是儿童协会,因为它应该映射底层FK.

因此,CascadeType.ALL@ManyToOne关联移动到@OneToMany应该使用mappedBy属性的属性,因为它是最有效的一对多映射.`


Kev*_*sox 18

从EJB3.0规范:

可以使用级联注释元素来将操作的效果传播到关联实体.级联功能最常用于父子关系.

如果X是托管实体,则删除操作会导致其被删除.如果从X到这些其他实体的关系使用cascade = REMOVE或cascade = ALL注释元素值进行注释,则删除操作将级联到由X引用的实体.

简而言之,定义的实体关系CascadeType.All将确保所有持久性事件(如父级上发生的持久性,刷新,合并和删除)将传递给子级.定义其他CascadeType选项为开发人员提供了对实体关联如何处理持久性的更细粒度的控制.

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


Emi*_*and 9

在JPA 2.0中,如果要从用户实体中删除地址,则要删除地址,可以添加orphanRemoval=true(而不是CascadeType.REMOVE)地址@OneToMany.

之间更多的解释orphanRemoval=trueCascadeType.REMOVE在这里.


小智 5

如果您只想删除分配给用户的地址而不影响 User 实体类,您应该尝试以下操作:

@Entity
public class User {
   @OneToMany(mappedBy = "addressOwner", cascade = CascadeType.ALL)
   protected Set<Address> userAddresses = new HashSet<>();
}

@Entity 
public class Addresses {
   @ManyToOne(cascade = CascadeType.REFRESH) @JoinColumn(name = "user_id")
   protected User addressOwner;
}
Run Code Online (Sandbox Code Playgroud)

这样您就不必担心在注释中使用 fetch。但请记住,删除用户时,您还将删除与用户对象的连接地址。