【问题标题】:Challenge Persisting Complex Entity using Spring Data JDBC挑战使用 Spring Data JDBC 持久化复杂实体
【发布时间】:2020-08-17 04:42:35
【问题描述】:

考虑到 JPA 涉及的复杂性,我们计划将 Spring Data JDBC 用于我们的实体,因为它很简单。以下是示例结构,我们最多有 6 个子实体。我们能够通过适当的外键映射成功地将数据插入到这些实体中。

挑战:- 我们在此应用程序之外有一个工作流程,它会定期更新“请求”实体中的“请求状态”,这是创建请求后唯一更新的字段。与 Spring Data 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);
}

【问题讨论】:

  • 大家好,这是我在 SO 中的第一篇文章。如果我需要更清楚地说明问题,请告诉我。回到我的问题,因为只有一列被更新,现在我已经使用 @Query() 直接触发 UPDATE 查询,但这没有再次触发删除和插入。也就是说,如果这是正确的方法或有任何解决方法,我确实希望得到您的反馈。感谢您的回复。

标签: spring-boot spring-data spring-data-jdbc


【解决方案1】:

您在评论中描述的方法:

有一个专门的方法来执行更新语句是正确的方法。

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

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

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

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

为了避免这个或类似的问题,你需要

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

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

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

【讨论】:

  • 感谢您的详细回复。我们将利用此处提供的方法进行乐观锁定。我认为拥有 2 个或更多 sql 语句而不是 JPA 的开销是一个很好的权衡,因为我们已经在我们的应用程序中使用 JdbcTemplate 来实现一些其他功能。
猜你喜欢
  • 2020-04-14
  • 2014-10-20
  • 1970-01-01
  • 2016-01-31
  • 2015-08-16
  • 1970-01-01
  • 2017-03-07
  • 2020-11-02
  • 1970-01-01
相关资源
最近更新 更多