使用Spring Data通过与现有实体的关系来保存新实体的正确方法

时间:2017-03-07 19:19:54

标签: spring-data spring-data-jpa

我工作的公司正在转换为Spring Data,我们大多数人仍在学习。我一直遇到一个我无法解决的问题。如何处理保存或更新与分离实体有关系的实体,其中这些实体中的值可能需要更改。

我有service,rate_plan和service_rate_plan表。 rate_plan表连接service和rate_plan表,它有一列用于该费率计划中的服务成本。

让我们假设用户想要创建一个费率计划。我创建了一个费率计划DTO,并向其添加了所有可能的serviceRatePlan列表。我把它呈现给用户。然后,用户添加费率计划的信息并设置一个或多个服务的成本并提交表单。

现在我有一个费率计划DTO,其中填写了一些信息,以及一份可能有或没有成本的serviceRatePlan列表。

对于更新,我公司的当前做法是获取serviceRatePlan的列表并对其进行迭代,并使用新信息更新现有列表的新列表。

这对我来说似乎并不合适。如果服务列表是10项,我想它可能没问题。但是,如果列表是1000个项目或类似的东西,在我看来,它将是非常低效的。

那么正确,最有效的方法是什么?

这是我目前正在合并的一个例子

protected void buildServiceListFromDto(RatePlan ratePlan, List<RatePlanServiceClassDto> serviceClasses)
{
  Set<ServiceRatePlan> servicesForRatePlan = new HashSet<>();
  ratePlan.setServicesForRatePlan(servicesForRatePlan);

  if (serviceClasses != null)
  {
    for (RatePlanServiceClassDto serviceClassDto : serviceClasses)
    {
      if (serviceClassDto.getServices() != null)
      {
        for (RatePlanServiceDto serviceDto : serviceClassDto.getServices())
        {
          /*
           * Looking at the servrate table it looks as though empty values are not stored.
           */
          if (StringUtils.isNotEmpty(serviceDto.getAmount().toString()))
          {
            ServiceRatePlan serviceRatePlan = new ServiceRatePlan();
            serviceRatePlan.setAmount(serviceDto.getAmount().getValue());
            serviceRatePlan.setRatePlan(ratePlan);
            Service service = serviceRepository.findOne(serviceDto.getNumber());
            serviceRatePlan.setService(service);
            servicesForRatePlan.add(serviceRatePlan);
          }
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:1)

假设您参考Spring Data JPA。

这里正确的做法是使用JPA的功能,即级联配置。将引用的级联选项从RatePlan设置为ServiceRatePlan到Cascade.ALL,JPA会在您保存RatePlan时保存它们。

您可以从这里开始了解有关级联的更多信息:JPA @ManyToOne with CascadeType.ALL

在决定你想要级联的关系时,它有助于在Aggregate Roots中思考,就像你可以从Domain Driven Design那样思考它们。这个想法是你有密切相关的实体的聚合。在您的情况下RatePlanServiceRatePlan。每个聚合都有一个聚合根,在您的情况下为RatePlan。然后,您只有Aggregate Roots和通过级联连接到该根的所有元素的存储库,因此您不需要存储库。另请参阅http://static.olivergierke.de/lectures/ddd-and-spring/#ddd.building-blocks.aggregates