我目前有一个Parent实体,该实体的子代具有OneToMany映射,而子实体又具有其子代具有OneToMany映射,依此类推。总而言之,它最终变成了多个层次。我想知道什么是处理更新的最佳方法。到目前为止,这就是我所拥有的(为了简便起见,我已将一些类名重命名,并省略了getters / setter方法,因此请原谅任何错字)。
@Entity
@Table(name = "parent")
public class Parent implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "id")
private Long id;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "parent_id")
private List<Children> children = new ArrayList<>();
public void setChildren(List<Children> children) {
this.children.clear();
for (Children child : children) {
child.setParent(this);
}
this.children.addAll(children);
}
public void addChild(Children child) {
child.setParent(this);
this.children.add(child);
}
// additional setters and getters omitted for brevity
@Entity
@Table(name = "children")
public class Children implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "children_id")
private List<ChildrenOfChildren> childrenOfChildren = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;
// setters and getters omitted for brevity
@Entity
@Table(name = "children_of_children")
public class ChildrenOfChildren implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "children_of_children_id")
private List<ChildrenOfChildrenOfChildren> childrenOfChildrenOfChildren = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
private Children children;
// setters and getters omitted for brevity
...等等。我有一个JPA储存库类和一个使用该储存库类来获取我的Parent对象及其关联的子代和子代子代的服务类,等等。这符合我的预期。
我的问题是,如果给定Parent对象,我应该如何以一种优雅而有效的方式处理更新?客户会发送一个Protobuf请求,然后我将其映射到我创建的实体类。我目前正在这样做:
@Service
public class ParentService {
private final ParentRepository parentRepository;
private final ChildrenRepository childrenRepository;
private final ChildrenOfChildrenRepository childrenOfChildrenRepository;
// additional repos as needed for each level
@Autowired
public ParentService(ParentRepository parentRepository,
ChildrenRepository childrenRepository,
ChildrenOfChildrenRepository childrenOfChildrenRepository) {
this.parentRepository = parentRepository;
this.childrenRepository = childrenRepository;
this.childrenOfChildrenRepository = childrenOfChildrenRepository;
}
@Transactional
public void updateParent(ProtobufPojo pojo) {
Parent parentEntity = parentRepository.findById(pojo.getId()).get();
if (parentEntity == null) {
parentEntity = new Parent();
}
parentEntity.setField(pojo.getField());
parentEntity.setField2(pojo.getField2());
parentEntity.setChildren(mapChildren(pojo.getChildrenList()));
parentRepository.save(parentEntity );
}
@Transactional
public List<Children> mapChildren(List<ChildrenPojo> childrenPojoList) {
List<Children> childrenEntities = new ArrayList<>();
for (ChildrenPojo pojo : childrenPojoList) {
Children childrenEntity = childrenRepository.findById(pojo.getId()).get();
if (childrenEntity == null) {
childrenEntity = new Children();
}
childrenEntity.setField(pojo.getName());
// continue mapping children of children, and so on
childrenEntity.setChildrenOfChildren(mapChildrenOfChildren(pojo));
childrenEntities.add(childrenEntity);
}
return childrenEntities;
}
@Transactional
public List<ChildrenOfChildren> mapChildrenOfChildren(List<ChildrenOfChildrenPojo> childrenOfChildrenPojoList) {
// repeat...
}
}
这是解决此问题的正确方法吗?从顶级Parent那里,我实际上是在检查它是否存在,如果存在,则从客户端POJO映射其所有字段,然后继续向下至其子项,映射其字段,依此类推。我并不完全相信这是最好的方法,因为我实际上是在覆盖字段(即使它们是相同的),但是从目前为止我所看到的,这将处理更新,添加新节点以及删除节点。我想念什么吗?
任何建议将不胜感激。预先感谢!