我正在使用spring-data将数据持久化到mysql db。我有一个包含子实体列表的父实体:
@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)将失败。我如何确保在保留新的子项之前删除旧的子项?
我建议使用
existingParent.getChilds().clear();
parentRepository.save(existingParent)
existingParent.getChilds().addAll(newChilds);
由于(Hibernate JPA: @OneToMany delete old, insert new without flush)
如果您采用默认交易行为,则可以更改
return parentRepository.save(existingParent);
to
return existingParent;
已加载然后更改的实体将在事务提交时自动保存,因此您实际上要保存两次。