使用Spring Data JDBC挑战持久化复杂实体

问题描述

考虑到JPA涉及的复杂性,我们正计划将Spring Data 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);
}

解决方法

您在评论中描述的方法:

具有专用的方法来准确执行更新语句,这是执行此操作的正确方法。

您应该知道,尽管这确实忽略了乐观锁定。 因此有可能发生以下情况

线程/会话1:读取聚合。

线程/会话2:根据您的问题更新一个字段。

线程/会话1:写入聚合(可能还会进行其他更改),覆盖会话2所做的更改。

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

  1. 检查聚合根的版本与加载时保持一致,以确保该方法不会写入冲突的更改。

  2. 增加版本,以确保没有其他东西会覆盖此方法中所做的更改。

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