我有一个关于将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<>();
仅当我在保持关系所有者之前链接实体的两侧时才起作用:
sharedAdvertisementKey.setSharedAdvertisement(sharedAdvertisement); sharedAdvertisement.addSharedAdvertisementKey(sharedAdvertisementKey);
因此,主要问题是:即使在关系方的所有者上有CascadeType.All,我也应该始终照顾双方吗?
您正在混合两个非常不同的概念。
A CascadeType处理将什么动作串连到关系。当指定时CascadeType.ALL,您告诉持久性提供者,只要您持久,合并或删除该实体,这些操作都将被复制到关系中。
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; }
这些方法可确保根据您的要求正确维护a PostDetails和a 之间的关系Post。因此,假设以下映射:
PostDetails
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因为我想确保Post和之间的关系PostDetails已初始化。
addDetails
setDetails
希望能有所帮助。