使用 Spring 数据 JDBC 挑战持久性复杂实体

Challenge Persisting Complex Entity using Spring Data JDBC

考虑到 JPA 中涉及的复杂性,我们计划为我们的实体使用 Spring 数据 JDBC 以实现其简单性。下面是示例结构,我们有多达 6 个子实体。我们能够使用适当的外键映射将数据成功插入到这些实体中。

挑战:- 我们在这个应用程序之外有一个工作流程,它会定期更新“请求”实体中的“requestStatus”,这是创建请求后唯一更新的字段。与 spring 数据 JDBC 一样,在更新期间它会删除所有引用的实体并再次重新创建(插入)它。考虑到 6 个子实体,这是一种繁重的操作。关于如何处理这些情况,是否有任何解决方法或建议

@Table("Request")
public class Request {

private String requestId; // generated in the Before Save Listener .

private String requestStatus;

@Column("requestId")
private ChildEntity1 childEntity1;

public void addChildEntity1(ChildEntity1 childEntityobj) {

   this.childEntity1 = childEntityobj;

  }

}
@Table("Child_Entity1")
public class ChildEntity1 {

    private String entity1Id; // Auto increment on DB

    private String name;

    private String SSN;

    private String requestId;

    @MappedCollection(column = "entity1Id", keyColumn = "entity2Id")
    private ArrayList<ChildEntity2> childEntity2List = new ArrayList<ChildEntity2>();

    @MappedCollection(column = "entity1Id", keyColumn = "entity3Id")
    private ArrayList<ChildEntity3> childEntity3List = new ArrayList<ChildEntity3>();

    public void addChildEntity2(ChildEntity2 childEntity2obj) {

        childEntity2List.add(childEntity2obj);
    }

    public void addChildEntity3(ChildEntity3 childEntity3obj) {

        childEntity3List.add(childEntity3obj);
    }

}
@Table("Child_Entity2")
public class ChildEntity2 {

    private String entity2Id; // Auto increment on DB

    private String partyTypeCode;
    
    private String requestId;

}
@Table(Child_Entity3)
public class ChildEntity3 {

    private String entity3Id; // Auto increment on DB

    private String PhoneCode;

    private String requestId;

}
@Test
public void createandsaveRequest() {

    Request newRequest = createRequest(); // using builder to build the object
    newRequest.addChildEntity1(createChildEntity1());
    newRequest.getChildEntity1().addChildEntity2(createChildEntity2());
    newRequest.getChildEntity1().addChildEntity3(createChildEntity3());
    requestRepository.save(newRequest);
}

您在评论中描述的方法:

有一个专门的方法来执行 update-statement 是正确的方法。

你应该知道这确实忽略了乐观锁定。 因此存在以下可能发生的风险

Thread/Session 1: 读取聚合。

Thread/Session 2:根据您的问题更新单个字段。

Thread/Session 1:写入聚合,可能还有其他更改,覆盖会话 2 所做的更改。

要避免此问题或类似问题,您需要

  1. 检查聚合根的版本与加载时的版本是否相同,以保证该方法不会写入冲突的更改。

  2. 增加版本以保证没有其他任何东西覆盖在此方法中所做的更改。

这可能意味着您需要两个或更多 SQL 语句,这可能意味着您必须更多地回退到实现它的完整自定义方法,可能使用注入的 JdbcTemplate