JPA OneToMany坚持使用CascadeType.ALL不会持续孩子 [英] JPA OneToMany persist with CascadeType.ALL doesn't persist child

查看:190
本文介绍了JPA OneToMany坚持使用CascadeType.ALL不会持续孩子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆