JPA OneToMany坚持使用CascadeType.ALL不会持续孩子 [英] JPA OneToMany persist with CascadeType.ALL doesn't persist child
问题描述
我有一个关于使用JPA与OneToMany关系(双向)以及CascadeType.ALL的问题。基于弗拉德发布( https:// vladmihalcea。 com / a-beginners-guide-to-jpa-and-hibernate-cascade-types / ),使用CascadeType.ALL坚持OneToMany关系,也应该持久
发帖=新帖子();
post.setName(Hibernate Master Class);
评论comment1 =新评论();
comment1.setReview(Good post!);
评论comment2 =新评论();
comment2.setReview(Nice post!);
post.addComment(comment1);
post.addComment(comment2);
session.persist(post);
但是,就我而言:
//实体SharedAdvertisementKey
@ManyToOne
@JoinColumn(name =SHARED_AD_ID,nullable = false)
private SharedAdvertisement sharedAdvertisement;
//实体SharedAdvertisements
@OneToMany(mappedBy =sharedAdvertisement,cascade = CascadeType.ALL)
private List< SharedAdvertisementKey> sharedAdvertisementKey = new ArrayList<>();
只有在持久关系所有者之前将实体的两侧链接时才有效:
sharedAdvertisementKey.setSharedAdvertisement(sharedAdvertisement);
sharedAdvertisement.addSharedAdvertisementKey(sharedAdvertisementKey);
所以主要问题是:我是否应该始终照顾双方,即使CascadeType所有关系方的所有者?
您正在混合两种截然不同的概念。 b
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;
$ b 这些方法可以确保 PostDetails
和一个邮政
根据您的要求妥善维护。因此,假设以下映射:
public class Post {
@OneToOne(cascade = CascadeType.ALL,mappedBy = post,orphanRemoval = true)
私人PostDetails细节;
$ b 您可以按如下方式执行它们的持久性操作:
PostDetails details = new PostDetails();
details.setUser(currentUser);
Post post = new Post();
post.addDetails(details);
session.persist(post);
您注意到我使用了 addDetails
,而不是典型的 setDetails
因为我想确保 Post
和 PostDetails code>已初始化。
希望有帮助。
I've got the question about using JPA with OneToMany relationship (bidirectional) along with CascadeType.ALL. Basing on vlad post (https://vladmihalcea.com/a-beginners-guide-to-jpa-and-hibernate-cascade-types/), persisting in OneToMany relationship using CascadeType.ALL, should also persist
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);
But, in my case:
//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<>();
It's only working when i link both sides of entities before persisting the owner of relationship:
sharedAdvertisementKey.setSharedAdvertisement(sharedAdvertisement);
sharedAdvertisement.addSharedAdvertisementKey(sharedAdvertisementKey);
So the main question is: Should I take care of both sides always, even if there is a CascadeType.All on the owner of relationship side?
解决方案 You're mixing two very different concepts.
A CascadeType
deals with what actions cascade to relations. When specifying CascadeType.ALL
, you are telling the persistence provider that whenever you persist, merge, or remove that entity, those actions are to be replicated to the relations.
But in order for cascade operations to work, you must first make sure that the relationship is managed correctly. If you look at Vlad's post, you'll notice two very important methods on Post
.
public void addDetails(PostDetails details) {
this.details = details;
details.setPost( this );
}
public void removeDetails() {
this.details.setPost( null );
this.details = null;
}
These methods make sure that the relationship between a PostDetails
and a Post
is properly maintained based on your requirements. So assuming the following mapping:
public class Post {
@OneToOne(cascade = CascadeType.ALL, mappedBy = "post", orphanRemoval = true)
private PostDetails details;
}
You could perform the persistence operation of both of them as follows:
PostDetails details = new PostDetails();
details.setUser( currentUser );
Post post = new Post();
post.addDetails( details );
session.persist( post );
You notice I used the addDetails
rather than the typical setDetails
because I wanted to make sure that the relationship between Post
and PostDetails
was initialized.
Hope that helps.
这篇关于JPA OneToMany坚持使用CascadeType.ALL不会持续孩子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!