一对多关系:使用 JPA 2.0 更新已删除的子项

2024-06-28

我有双向一对多关系。

0 or 1 client 0 个或多个列表产品订单.

应在两个实体上设置或取消设置该关系: 在客户端,我想设置分配给客户端的产品订单列表;然后应将客户端设置/取消设置为自动选择的订单。 在产品订单方面,我想设置分配订单的客户;然后,该产品订单应从其先前分配的客户列表中删除,并添加到新分配的客户列表中。

我想使用纯 JPA 2.0 注释和仅对实体管理器的一次“合并”调用(带有级联选项)。我尝试过以下代码片段,但它不起作用(我使用 EclipseLink 2.2.0 作为持久性提供程序)

@Entity
public class Client implements Serializable {
    @OneToMany(mappedBy = "client", cascade= CascadeType.ALL)
    private List<ProductOrder> orders = new ArrayList<>();

    public void setOrders(List<ProductOrder> orders) {
        for (ProductOrder order : this.orders) {
            order.unsetClient();
            // don't use order.setClient(null);
            // (ConcurrentModificationEx on array)
            // TODO doesn't work!
        }
        for (ProductOrder order : orders) {
            order.setClient(this);
        }
        this.orders = orders;
    }

    // other fields / getters / setters
}

@Entity
public class ProductOrder implements Serializable {
    @ManyToOne(cascade= CascadeType.ALL)
    private Client client;

    public void setClient(Client client) {
        // remove from previous client
        if (this.client != null) {
            this.client.getOrders().remove(this);
        }

        this.client = client;

        // add to new client
        if (client != null && !client.getOrders().contains(this)) {
            client.getOrders().add(this);
        }
    }

    public void unsetClient() {
        client = null;
    }

    // other fields / getters / setters
}

持久化客户端的外观代码:

// call setters on entity by JSF frontend...
getEntityManager().merge(client)

持久化产品订单的门面代码:

// call setters on entity by JSF frontend...
getEntityManager().merge(productOrder)

在订单端更改客户分配时,效果很好:在客户端,订单将从之前的客户列表中删除,并添加到新客户的列表中(如果重新分配)。

BUT 在客户端更改时,我只能添加订单(在订单端,执行对新客户端的分配),但当我从客户端列表中删除订单时,它只是忽略(保存并刷新后,它们仍然在客户端的列表中,在订单端,他们也仍然分配给以前的客户。

只是为了澄清,我不想使用“删除孤儿”选项:从列表中删除订单时,不应将其从数据库中删除,但应更新其客户端分配(即更新为 null),如 Client#setOrders 方法中所定义。如何才能实现这一点?


EDIT: 感谢我在这里收到的帮助,我能够解决这个问题。请参阅下面我的解决方案:

客户端 (“一”/“拥有”方) 将已修改的订单存储在临时字段中。

@Entity
public class Client implements Serializable, EntityContainer {

    @OneToMany(mappedBy = "client", cascade= CascadeType.ALL)
    private List<ProductOrder> orders = new ArrayList<>();

    @Transient
    private List<ProductOrder> modifiedOrders = new ArrayList<>();

    public void setOrders(List<ProductOrder> orders) {
    if (orders == null) {
        orders = new ArrayList<>();
    }

    modifiedOrders = new ArrayList<>();
    for (ProductOrder order : this.orders) {
        order.unsetClient();
        modifiedOrders.add(order);
        // don't use order.setClient(null);
        // (ConcurrentModificationEx on array)
    }

    for (ProductOrder order : orders) {
        order.setClient(this);
        modifiedOrders.add(order);
    }

    this.orders = orders;
    }

    @Override // defined by my EntityContainer interface
    public List getContainedEntities() {
        return modifiedOrders;
}

On the facade,在持久化时,它会检查是否还有任何必须持久化的实体。请注意,我使用了一个接口来封装此逻辑,因为我的外观实际上是通用的。

// call setters on entity by JSF frontend...
getEntityManager().merge(entity);

if (entity instanceof EntityContainer) {
    EntityContainer entityContainer = (EntityContainer) entity;
    for (Object childEntity : entityContainer.getContainedEntities()) {
        getEntityManager().merge(childEntity);
    }
}

JPA 不执行此操作,据我所知,也没有 JPA 实现执行此操作。 JPA 要求您管理关系的双方。当仅更新关系的一侧时,有时称为“对象损坏”

JPA 确实在双向关系中定义了一个“拥有”方(对于 OneToMany,这是没有mappedBy 注释的一方),它用于在持久化到数据库时解决冲突(只有一种表示形式)数据库中的关系与内存中的两个关系进行比较,因此必须做出解决方案)。这就是为什么可以实现对 ProductOrder 类的更改,但不能对 Client 类进行更改。

即使是“拥有”关系,您也应该始终更新双方的情况。这通常会导致人们只依赖更新一侧,而当他们打开二级缓存时就会遇到麻烦。在 JPA 中,只有当对象被持久化并从数据库重新加载时,上述冲突才会得到解决。一旦二级缓存打开,接下来可能会发生多个事务,同时您将处理损坏的对象。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一对多关系:使用 JPA 2.0 更新已删除的子项 的相关文章

  • 找不到兼容的方法:将对象传递给方法时出错?

    我正在尝试为我们拥有的一些旧的遗留代码编写junit 下面是我正在为其编写 junit 并使用 jmockit 的 DataLogger 类中的方法 private Object extractMessageObjects final Ob
  • 将文件复制到资产文件夹

    经过 1 小时的搜索 我没有找到任何解决我的问题的方法 我想将文件从SD卡移动到资产文件夹 并覆盖资产文件夹中的现有文件 两个文件都是sqlite数据库 名称相同 数据略有不同 实际上 android apk 文件的行为是只读的 因此该 a
  • 记录所有 presto 查询

    如何将提交到 presto 集群的所有查询存储在文件 ORC 文件 或其他数据库中 目的是保存在 presto 工作线程上执行的所有查询的记录 我知道我需要覆盖 queryCompleted 方法 我也尝试遵循this https grou
  • 如何将 Postgres JSONB 数据类型与 JPA 结合使用?

    我没有找到使用 JPA EclipseLink 从 PostgreSQL 映射 JSON 和 JSONB 数据类型的方法 有人在 JPA 中使用这种数据类型并且可以给我一些工作示例吗 所有答案都帮助我找到了适合 JPA 的最终解决方案 而不
  • Java - 加载 .OBJ 文件

    我希望能够从 obj 文件获取信息 例如子组件的名称 那里有装载机可以做到这一点吗 Java3D 有一个 ObjectFile 但是我见过的方法列表让我觉得它不完全是我想要的 我自己解析文件会更好吗 谢谢 将要 几个月前我写了一个 java
  • Play2 - 模板 -> 递增

    如何在 play2 中声明并递增变量 在 scala html 模板 伪代码 counter for l lt list span class span counter 1 你真的需要计数器和递增吗 你可以这样做 for l index l
  • 如何在 Eclipse EE (Java) 上配置 mySQL

    下载 Java EE Eclipse Indigo EE mysql 5 5 从现在起我不知道如何直接从 eclipse 创建 mySQL 数据库 我已经找到了使用 WAMP 服务器的方法 但我并不打算这样做 我相信第一步在于以某种方式使用
  • 协程内的具体化泛型参数不起作用

    我正在创建 http json 客户端 我将 Volley 与协程结合使用 我想创建通用的 http 客户端 这样我就可以在任何地方使用它 我创建了通用扩展方法来将 JSON 字符串解析为对象 inline fun
  • 未知的 UTF-8 代码单元闭合双引号

    我的问题如下 我正在读取一个 XML 文件 其文本节点部分包含 UTF 8 版本的打开和关闭双引号 文本被提取 缩短为 3999 字节并放入新的 XML 格式 然后保存为文件 虽然 Notepad 在输入文件中正确显示了这两个符号 但输出文
  • Oreo 8.0 -“sendTextMessage()”未将消息保存到已发送文件夹

    我尝试使用 sendTextMessage 或 sendMultipartTextMessage 从我自己的应用程序发送短信 对于高于 API 19 KitKat 的手机 此消息将保存到已发送文件夹中 然而 在我的 Android 8 0
  • 无法将 Tomcat 作为 Windows 服务启动

    我在Windows 8上使用Tomcat6 我可以通过startup bat启动Tomcat 不会出现错误 我已将 Tomcat6 exe Tomcat6w exe 和 service bat 复制到 tomcat bin 目录下 并将 e
  • Excel 读取错误:标头签名无效。如何解决?

    我正在从浏览器上传一个 Excel 文件 我正在使用 POI jar 但出现错误 标头签名无效 读取 3255307777713450285 预期为 2226271756974174256 下面是我使用过的两个jsp文件 JSP 1
  • 获取Java InputStream后面的文件的字节数

    正如标题所示 我需要知道文件在输入流 后面 有多少字节 我不想下载所有字节和计数 需要很长时间 我只需要知道文件有多少字节 像这样 int numberOfBytes countBytes inputStream 所以 我需要 countB
  • 如果没有发生触摸事件,Android SurfaceView 会变慢

    我正在制作一款游戏 除了游戏循环之外一切都很顺利 我正在使用 SurfaceView 并绘制 2D Sprites 位图 目前游戏是一艘穿过小行星带的飞船 飞船停留在屏幕中央 手机向任一方向倾斜以移动小行星 小行星改变位置而不是玩家 当旧的
  • 当我尝试使用 LWJGL 库加载声音时,为什么会收到错误“NoClassDefFoundError: sun/misc/Unsafe”?

    This is the screenshot of my Eclipse project files 当我尝试启动时出现以下错误new Sound Res MouseClick ogg 我的班级中的对象AudioPlayer在第 15 行
  • 在 Maven 存储库中查找 Oracle JDBC 驱动程序

    我想将 oracle jdbc 驱动程序作为依赖项 运行时范围 添加到我的项目中 ojdbc14 在 MVNrepository 站点中 放入 POM 的依赖项是
  • 在android 2.3.6中如何通过联系人提供程序获取联系人照片?

    我有这个适用于 android 4 的版本 String email是 Gmail 地址 private Uri getPhotoUriFromEmail String email Uri u null String projection
  • 按下 JButton 时运行函数

    我正在尝试用java编写一个程序 使用机器人每隔几秒按一次特定的键 它有一个带有开始和停止按钮的 GUI 以及一个告诉其处于哪个状态的标签 到目前为止 我已经完成了所有工作 除了当我单击 开始 时 它运行我的机器人功能的循环 这是无限的 没
  • FlyingSaucer renderer.setDocument 抛出“流已关闭”异常

    我在使用找到的简单示例创建 PDF 时遇到问题here http today java net pub a today 2007 06 26 generating pdfs with flying saucer and itext html
  • 使用 Jackson 反序列化非字符串映射键

    我有一张如下所示的地图 public class VerbResult JsonProperty similarVerbs private Map

随机推荐

  • 如何退格或删除?

    在 Windows 10 中 当我通过 Windows 上的 Kitematic 中的容器启动 MS PowerShell 进行 ssh 时 我注意到我无法退格或删除 而是得到 H 表示退格 而不是实际删除前一个字符 我错过了什么吗 接受的
  • (键,值)对结构的内存分配,并从注册表中读取

    我想制作一个程序 它从 Windows 注册表中收集一些信息 然后将其保存到文件中 但是我在收集信息时遇到了问题 我想将数组存储在结构中 我的问题是在初始化结构后指定数组的大小 typedef struct RESULTSKEY char
  • 什么时候需要浅拷贝(而不是深拷贝)?

    有人可以举一个需要浅拷贝的情况的例子吗 请注意 在某些情况下 浅复制和深复制是相同的 当对象对其任何子变量没有所有权时 就会发生这种情况 也就是说 所有子变量都是聚合的 http en wikipedia org wiki Object c
  • 级联的反向等效项是什么?

    我正在编写一个小型音乐数据库 我学习 SQL 已经有很长一段时间了 我一直想尝试一下 Django 但有一件事我无法理解 现在 我的模型仅包含两个类 Album and Song Song有一个外键指向它所属的相册 现在如果我删除它Albu
  • 为什么在 VS2008/Casini 中启动调试时 Application_Init 会触发两次?

    为什么在 VS2008 Casini 中启动调试时 Application Init 会触发两次 是的 它发生在 global asax 中 虽然看起来相当随机 但只偶尔发生一次 我假设您引用的是 ASP NET MVC 应用程序中的 Gl
  • 使用 deflater 压缩/解压缩字符串

    我想压缩 解压缩和序列化 反序列化字符串内容 我正在使用以下两个静态函数 Compress data based on the link Deflater param pToCompress input byte array return
  • Compass 和 SASS:没有编译错误

    我现在已经厌倦了这个问题 为了让这件事继续下去 我已经被推迟了很多次 我觉得这是我解决问题的最后一次尝试 开始 我安装指南针 sudo gem update system sudo gem install compass 我创建我的测试项目
  • rspec Rails 测试:如何强制 ActiveJob 作业内联运行某些测试?

    我希望我的后台作业能够内联运行某些标记的测试 我可以通过包装测试来做到这一点perform enqueued do但我希望能够用元数据标记它们 并且如果可能的话 它会自动发生 我尝试过以下方法 it does everything in t
  • iPhone 4后台定位服务问题

    我正在研究 iPhone 4 SDK 中新的后台位置服务选项 它允许应用程序在后台运行并从设备接收位置更新 提供了两种方法 一种是电池密集型模式 可以持续获取位置更新 第二种推荐的方法是在发生 重大位置变化 时发送应用程序位置更新 有谁知道
  • 我可以将 HTMLUnit 配置为仅运行特定的 javascript 进程而不是整个进程吗?

    我希望从一组格式非常相似的网页中收集信息 我需要一些在打开后由 Javascript 加载到页面上的信息 HTMLUnit 似乎是执行此操作的一个非常常见的工具 所以这就是我正在使用的工具 不幸的是 它非常慢 这是我在很多论坛上看到的抱怨
  • 在 iOS 中使用 webView 集成 Instagram 失败

    在我的应用程序中 我使用 webView 进行 Instagram 身份验证 首先它显示 Instagram 登录屏幕 成功登录后我正在获取 accessToken 然后我使用 accessToken 获取其他详细信息 这是我在 viewD
  • ggplot2 黑白配色方案的建议

    我正在使用 ggplot2 生成许多结构如下的图表 有没有一种简单的方法可以制作出黑白效果很好的东西 我确实读过这个question https stackoverflow com questions 2895319 how to add
  • 使用 dplyr::filter 创建 R 函数问题

    我查看了其他答案 但找不到使下面的代码起作用的解决方案 基本上 我正在创建一个函数inner join两个数据框和filter基于函数中输入的列 问题是filter部分功能不起作用 但是 如果我将过滤器从函数中取出并附加它 它就会起作用my
  • 调用 Bitmap.GetHicon 时 GDI+ 中发生一般错误

    为什么我收到 GDI 中发生一般错误 异常 IntPtr hicon tempBitmap GetHicon Icon bitmapIcon Icon FromHandle hicon return bitmapIcon 当我的应用程序运行
  • ARKit:如何判断用户的脸部是否与相机平行

    In my Swift ARKit SceneKit项目中 我需要判断前置摄像头中用户的脸部是否与摄像头平行 我能够通过比较左眼和右眼的距离来判断水平平行 使用faceAnchor leftEyeTransform和worldPositio
  • 从 Unity 中的另一个脚本调用 IEnumerator 方法并获取其返回值

    我正在使用 Unity 开发一个项目 我有这个文件 API cs 不附加到任何游戏对象 using UnityEngine using UnityEngine Networking using System Collections usin
  • 文件上传进度条[重复]

    这个问题在这里已经有答案了 可能的重复 PHP 上传进度条 https stackoverflow com questions 849237 upload progress bar in php 任何人都可以建议一种在上传文件时包含文件上传
  • XMLHttpRequest.send 因相对路径而失败

    我在某些可能可以补救的事情上遇到了困难 我正在开发一个没有服务器的网站 这样做时 我在尝试通过 XMLHttpRequest 访问文件时遇到了问题 正如您在示例代码片段中看到的 我创建了变量 使用所需文件的相对路径打开它 然后使用发送函数
  • 如何在烧瓶模板中模拟“current_user”?

    我想嘲笑flask login s current user在模板渲染下 该函数返回当前登录的用户 现在我正在嘲笑AnnonymousUserMixin from flask login如果用户未经过身份验证 则默认返回该值 但这会导致各种
  • 一对多关系:使用 JPA 2.0 更新已删除的子项

    我有双向一对多关系 0 or 1 client 0 个或多个列表产品订单 应在两个实体上设置或取消设置该关系 在客户端 我想设置分配给客户端的产品订单列表 然后应将客户端设置 取消设置为自动选择的订单 在产品订单方面 我想设置分配订单的客户