JPA OneToMany 坚持 CascadeType.ALL 不坚持 child

JPA OneToMany persist with CascadeType.ALL doesn't persist child

我有关于将 JPA 与 OneToMany 关系(双向)与 CascadeType.ALL 一起使用的问题。基于 vlad post (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<>();

只有当我 link 实体的双方在持久化关系的所有者之前才有效:

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

所以主要问题是:我是否应该始终照顾双方,即使关系方的所有者有CascadeType.All?

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

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

但是为了使级联操作起作用,您必须首先确保正确管理关系。如果您查看 Vlad 的 post,您会注意到 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 之间的关系。

希望对您有所帮助。