当前位置: 首页 > 面试题库 >

JPA OneToMany与CascadeType一起保留。ALL不会保留子项

卜飞鸣
2023-03-14
问题内容

我有一个关于将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,您告诉持久性提供者,只要您持久,合并或删除该实体,这些操作都将被复制到关系中。

但是,为了使级联操作起作用,必须首先确保正确管理该关系。如果查看Vlad的帖子,您会注意到上两个非常重要的方法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。因此,假设以下映射:

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已初始化。

希望能有所帮助。



 类似资料:
  • ALL ALL 关键字被使用在这些上下文之中: ALL、DISTINCT、DISTINCTROW、TOP 谓词 SQL 子查询 UNION 运算

  • 问题内容: 我正在使用用Java(Selenium)编写的外部库。其中一个函数调用具有签名,当尝试从Scala调用它时,我不断收到编译器错误,即: 有没有解决此问题的方法? 问题答案:

  • 为了便于编程,CodeIgniter使用了一系列的函数和名称来完成操作。所以,有些名称不能被程序员使用。下面是不能被程序员使用的保留字列表。 控制器 因为你的控制器类将继承主程序控制器,所以你的函数命名一定不能和主程序控制器类中的函数名相同,否则你的局部函数将会覆盖他们。下面列出了已经保留的名称,请不要将你的控制器命名为这些: Controller CI_Base _ci_initialize D

  • 问题内容: 我正在尝试使用setRetainInstance(),但似乎对我不起作用!=(。我将问题简化为最简单的版本: 我有一个带有TextView和Button的片段。 当按下按钮时,TextView的初始文本为“我在等待”,文本变为“ Hello!”。 那是我的代码: 片段: 活动: 活动的布局: 片段的布局: 但是当我播放它时,按下按钮并更改设备的方向,文字将被重置。 我想念什么?我该如何

  • 我创建了一个API来登录我的web应用程序。检查参数后,使用Auth方法:loginUsingId()和要登录的用户的id 在正确验证之后,实际上执行echo Auth::user()可以正确显示用户属性 但是,通过重定向到另一个项目页面,我将不再登录门户并显示登录页面 用户的会话似乎没有保留或根本没有创建 我使用Laravel 5.6。我没有路线的中间件。

  • 问题内容: 我不确定这是否可能。 我的“活动”网站正在处理注册并将其保存到我们的数据库中,但是我们的主站点负责处理信用卡处理。通过在主网站上处理当前的购买,会话可用于将数据传递到付款/抄送屏幕。 不必更改我的付款代码(例如接受$ _GET参数),我的变量是否应该传递过来? 例: 我的页面在上面查找地址会话变量。 问题答案: 跨域会话ID 默认情况下,使用cookie传递会话ID。由于您的网站位于不