Связи и агрегаты

Базовый Spring
≈ 2 мин чтения

Главная идея — aggregate

Spring Data JDBC рассматривает связанные объекты не как произвольный граф сущностей, а через границы aggregate. У агрегата есть корень — объект, через который внешняя часть приложения загружает и сохраняет всё связанное целое. Это помогает явно решить, какие данные должны изменяться вместе в одной операции репозитория.

@Table("orders")
class Order {
    @Id
    Long id;

    String customerEmail;

    @MappedCollection(idColumn = "order_id")
    Set<OrderItem> items = new HashSet<>();
}

@Table("order_items")
class OrderItem {
    @Id
    Long id;

    String product;
    int quantity;
}

Здесь Order — корень агрегата, а элементы заказа входят в его состав. Столбец order_id в таблице элементов связывает строки с владельцем агрегата. Сохранение заказа означает сохранение состояния этого целого согласно модели Spring Data JDBC.

Связь между разными агрегатами

Если два объекта живут независимо и изменяются через разные репозитории, обычно их не стоит соединять в один автоматически сохраняемый объектный граф. Между такими агрегатами чаще хранится идентификатор другого агрегата. Например, заказ может хранить customerId, не включая весь объект клиента внутрь себя.

Граница агрегата влияет не только на дизайн классов, но и на SQL при сохранении. Слишком большой агрегат делает даже небольшое изменение дорогой операцией, поэтому в него стоит включать только данные, которые действительно должны согласованно сохраняться вместе.