JPA合并仅更新已更改的列

时间:2017-03-16 21:12:52

标签: java hibernate jpa merge

我有电话的客户:

public class Customer {

    ...

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "customer_id", nullable = false)
    private List<Phone> phones = new ArrayList<>();

}


public class Phone {

    ...

    @Column(name = "customer_id", insertable = false, updatable = false)
    private Long customer_id;

}

如果我尝试em.merge(customer);,那么JPA将始终插入所有映射列(如果电话或电话有新ID,那么它们将被插入)并且只会更新已更改的列(如果电话已存在id更改,然后会更新)。

但如果我尝试合并手机列表为空的客户那么没有任何反应。这里的问题是如何以发布方式合并客户电话。例如,如果电话列表为空,则它将为空。

初始状态:

{
    "id" : "1",
    "phones" : []
}

现在张贴:

{
"id" : "1",
"phones" : [
        {
            "id" : "12",
            "type" : "mobile",
            "value" : "123"
        }
    ]
}

如果不存在具有此ID的手机,则会添加新手机。如果有手机ID为12,那么它将被更新。所以在我们的情况下,id为12的手机不存在,那么在帖子后结果是相同的:

{
"id" : "1",
"phones" : [
        {
            "id" : "12",
            "type" : "mobile",
            "value" : "123"
        }
    ]
}

但现在如果我发布:

{
    "id" : "1",
    "phones" : []
}

然后结果仍然相同:

{
"id" : "1",
"phones" : [
        {
            "id" : "12",
            "type" : "mobile",
            "value" : "123"
        }
    ]
}

但我认为这将是我插入它的方式,结果就是:

{
    "id" : "1",
    "phones" : []
}

为什么em.merge(客户)不这样做?

保存功能在这里:

@Transactional
    public void save(Customer customer) {
        if (customer.getId() == null) {
            em.persist(customer);
        } else {
            em.merge(customer);
        }
    }

一些hackish解决方案?

  • 我可以执行em.remove(customer)然后em.persist(customer)之类的操作。这可行,但我知道这可以通过em.merge(customer)实现。
  • 或者我可以找到特定的客户电话,然后删除它们 最后做合并。这也有效。但我仍然认为em.merge()能够以某种方式单独做到这一点。

0 个答案:

没有答案