Search code examples
springhibernateserviceentitydomain-driven-design

Method in Entity need to load all data from aggregate, how to optimalize this?


I've problem with aggregate which one will increase over time. One day there will be thousands of records and optimalization gonna be bad.

@Entity
public class Serviceman ... {

  @ManyToMany(mappedBy = "servicemanList")
  private List<ServiceJob> services = new ArrayList<>();

  ...


public Optional<ServiceJob> firstServiceJobAfterDate(LocalDateTime dateTime) {
        return services.stream().filter(i -> i.getStartDate().isAfter(dateTime))
                .min(Comparator.comparing(ServiceJob::getStartDate));
    }

}

Method just loading all ServiceJob to get just one of them. Maybe I should delegate this method into service with native sql.


Solution

  • You have to design small aggregates instead of large ones.

    This essay explains in detail how to do it: http://dddcommunity.org/library/vernon_2011/. It explains how to decompose your aggregates to smaller ones so you can manage the complexity.

    In your case instead of having an Aggregate consisting of two entities: Serviceman and Servicejob with Serviceman being the aggregate root you can decompose it in two smaller aggregates with single entity. ServiceJob will reference Serviceman by ID and you can use ServicejobRpository to make queries.

    In your example you will have ServicejobRpository.firstServiceJobAfterDate(guid servicemanID, DateTime date).

    This way if you have a lot of entities and you need to scale, you can store Servicejob entities to another DB Server.

    If for some reason Serviceman or Servicejob need references to each other to do their work you can use a Service that will use ServicemanRepository and ServicejobRepository to get both aggregates and pass them to one another so they can do their work.