JPA OneToMany 使用 CascadeType.ALL 不持久子项



我有一个关于使用OneToMany关系(双向)的JPA和CascadeType.ALL的问题(https://vladmihalcea.com/a-beginners-guide-to-jpa-and-hibernate-cascade-types/),使用CascadeType.ALL持久化OneToMany关系,也应持久化

Post post = new Post();
post.setName("Hibernate Master Class");
Comment comment1 = new Comment();
comment1.setReview("Good post!");
Comment comment2 = new Comment();
comment2.setReview("Nice post!");
post.addComment(comment1);
post.addComment(comment2);
session.persist(post);

但是,就我而言:

//Entity SharedAdvertisementKey
@ManyToOne
@JoinColumn(name="SHARED_AD_ID", nullable=false)
private SharedAdvertisement sharedAdvertisement;
//Entity SharedAdvertisements
@OneToMany(mappedBy="sharedAdvertisement", cascade=CascadeType.ALL)
private List<SharedAdvertisementKey> sharedAdvertisementKey = new ArrayList<>();

只有当我在持久化关系的所有者之前链接实体的双方时,它才有效:

sharedAdvertisementKey.setSharedAdvertisement(sharedAdvertisement);
sharedAdvertisement.addSharedAdvertisementKey(sharedAdvertisementKey);

所以主要的问题是:我应该一直照顾双方吗,即使有级联类型。一切都在关系方?

您混合了两个截然不同的概念。

CascadeType处理哪些动作级联到关系。指定CascadeType.ALL时,您告诉持久性提供程序,无论何时持久化、合并或删除该实体,这些操作都将复制到关系中。

但是,为了使级联操作发挥作用,您必须首先确保正确管理关系。如果你看看Vlad的帖子,你会注意到Post上有两个非常重要的方法。

public void addDetails(PostDetails details) {
  this.details = details;
  details.setPost( this );
}
public void removeDetails() {
  this.details.setPost( null ); 
  this.details = null;
}

这些方法确保PostDetailsPost之间的关系根据您的需求得到正确维护。因此,假设以下映射:

public class Post {
  @OneToOne(cascade = CascadeType.ALL, mappedBy = "post", orphanRemoval = true)
  private PostDetails details;
}

您可以按如下方式执行它们的持久性操作:

PostDetails details = new PostDetails();
details.setUser( currentUser );
Post post = new Post();
post.addDetails( details );
session.persist( post );

您注意到,我使用了addDetails而不是典型的setDetails,因为我想确保PostPostDetails之间的关系已初始化。

希望能有所帮助。

最新更新