【问题标题】:Spring Data: How to update a List of childs with unique constraintsSpring Data:如何更新具有唯一约束的子列表
【发布时间】:2019-11-27 08:17:52
【问题描述】:

我正在使用 spring-data 将数据持久化到 mysql 数据库。 我有一个包含子实体列表的父实体:

@Entity
public class Parent
{
    private Long id;

    @Unique
    private String name;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "parent_id")
    private List<Child> childs;

    // Getter, Setter
}

这是子实体:

@Entity
@Table(
    uniqueConstraints = { @UniqueConstraint(columnNames = { "parent_id", "name" }) }
)
public class Child
{
    private Long id;

    @Unique
    private String name;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "parent_id")
    private Parent parent;

    // Getter, Setter
}

在数据库中,我在这两个类中具有相同的活动约束。 现在,我想像这样更新父母的孩子:

@Service
public class ParentService
{
    // ...

    @Transactional
    public Parent updateParent(String name, List<Child> newChilds)
    {
        Parent existingParent = parentRepository.findByName(name);
        existingParent.setChilds(newChilds);
        return parentRepository.save(existingParent);
    }

    // ...
}

但是,如果孩子的唯一约束(名称 + parent_id)具有相同的名称,则它们将失败。我怎样才能确定在新的孩子被持久化之前旧的孩子被删除了?

【问题讨论】:

    标签: mysql spring-data-jpa spring-data constraints


    【解决方案1】:

    我建议使用

    existingParent.getChilds().clear();
    parentRepository.save(existingParent)
    existingParent.getChilds().addAll(newChilds);
    

    因为 (Hibernate JPA: @OneToMany delete old, insert new without flush)

    如果你是默认交易行为,你可以改变

    return parentRepository.save(existingParent);
    

    return existingParent;
    

    加载然后更改的实体会在事务提交时自动保存,因此您实际上保存了两次。

    【讨论】:

    • 谢谢,你说得对,在父级新建列表不好,我也可以去掉现有实体对象的手动保存。我不知道hibernate观察他的模型那么复杂,看来我应该多研究一些关于hibernate/jpa的知识。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 2018-07-25
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多