【问题标题】:Spring JPA implementing "save changes" in one callSpring JPA 在一次调用中实现“保存更改”
【发布时间】:2016-04-30 20:19:13
【问题描述】:

我们有一个页面,用户可以在其中更改对象(例如:公司)。该对象具有通用字段(例如:姓名、日期等)以及一些 @OneToMany 注释(地址、电话号码等)。

我们的要求是允许用户对前端进行更改,然后在单击按钮后保存这些更改。我们面临的问题是更新 OneToMany 关系。

考虑以下场景:

用户对现有地址(id:1)进行了更改,他们创建了一个新地址(无 id 项)并删除了现有地址(在请求中不可见)。

请求到达后端的数据:

{
    id: 1,
    name: "Edited company name",
    addresses: [
        {
            id: 1,
            name: "modified address",
            line1: "12 Main street"
        },
        {
            name: "This is a new address without an id",
            line1: "5 Someother Street",
        }
    ]
}

默认情况下,我们有 2 个选项:

选项 1:

弹簧配置:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "company", orphanRemoval = true)
@Cascade(org.hibernate.annotations.CascadeType.ALL)

使用此配置,删除的地址不是 JSON 的一部分,因此“orphanRemoval”选项可确保所有未在 JSON 中传递的地址都将被删除。这里的问题是,没有办法指定只删除一个地址,而不是删除所有不属于 JSON 的公司地址。

选项 2:

弹簧配置:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
@Cascade(org.hibernate.annotations.CascadeType.ALL)

此处的 orphanRemoval 选项为 false(即未设置)。所以这意味着创建了新地址,更新了现有地址,但没有删除任何内容。

所以我的问题是:在 Spring 中是否有更好/默认的方法来实现它,或者我们是否需要手动跟踪已删除的项目并实现我们自己的逻辑以确保只有我们想要删除的项目确实是删除了吗?

附言

我意识到这可以通过简单地调用 DELETE 并在单击按钮后删除地址来解决,但这里的想法是我们只在用户点击“SAVE”后才进行 DB 调用,这应该将所有更改发送到服务器一次。我们不能使用 DELETE 调用,因为如果用户决定点击“取消”而不保存他们的更改,我们就无法恢复这些调用。

【问题讨论】:

    标签: json spring hibernate rest jpa


    【解决方案1】:

    简而言之:按预期使用 jpa 并根据您的业务需求设置 orphanRemoval。如果您的域模型中的地址只能存在于公司的上下文中,您希望保留 orphanRemoval 标志。如果不是,则应将其设置为 false。

    我在您的方法中看到的问题是您希望将对象从浏览器合并回持久层。要完成这项工作,您必须在 json 请求中传输修改后公司的所有地址。

    最简洁的方法是引入 DTO 将您的 webapi 与域模型分开。这样,当您的 json 请求到达服务器时,您可以加载要使用 jpa 修改的域对象并在一个事务中进行所需的修改.更改会在提交时写回数据库。

    【讨论】:

      猜你喜欢
      • 2022-08-16
      • 1970-01-01
      • 2022-06-10
      • 2021-01-12
      • 2015-05-25
      • 1970-01-01
      • 2013-05-09
      • 2013-04-03
      • 2018-04-17
      相关资源
      最近更新 更多