2016-04-30 56 views
0

我们有一个用户可以对对象(如:公司)进行更改的页面。这个对象具有通用字段(例如:名称,日期等)以及一些@OneToMany注释(地址,电话号码等)。Spring JPA在一次调用中实现“保存更改”

我们的要求是允许用户对前端进行更改,然后单击按钮后保存这些更改。我们面临的问题是更新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:

Spring配置:

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

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

选项2:

Spring配置:

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

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

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

P.S.

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

回答

0

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

我用你的方法看到的问题是,你想将对象从浏览器合并到持久层。要做到这一点,你必须在json请求中传输修改过的公司的所有地址。

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

相关问题