Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
918 views
in Technique[技术] by (71.8m points)

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...