Аксон неявно создает экземпляр другого агрегата, используя конструктор без параметров - PullRequest
0 голосов
/ 27 января 2020

Мне просто интересно, почему Аксон неявно создает другой агрегат. Такое поведение вызывает обработку нескольких событий, и я не думаю, что эти издержки ожидаются. Имея эту конечную точку:

@PostMapping("ship")
public void shipOrder(@RequestBody Product product) {
        String orderId = UUID.randomUUID().toString();
        commandGateway.sendAndWait(new PlaceOrderCommand(orderId, product.getName()));
        commandGateway.sendAndWait(new ConfirmOrderCommand(orderId));
}

и следующую совокупность:

@Aggregate
public class Order {

    @AggregateIdentifier
    private String orderId;
    private boolean orderConfirmed;

    @CommandHandler
    public Order(PlaceOrderCommand command) {
        System.out.println("Calling COMMAND constructor");
        apply(new OrderPlacedEvent(command.getOrderId(), command.getProduct()));
    }

    protected Order() {
        System.out.println("Calling PARAMLESS constructor");
    }

    @CommandHandler
    public void handle(ConfirmOrderCommand command) {
        apply(new OrderConfirmedEvent(command.getOrderId()));
    }

    @EventSourcingHandler
    public void on(OrderPlacedEvent event) {
        System.out.println(">>>>>> Handling OrderPlacedEvent: " + this);
        this.orderId = event.getOrderId();
        orderConfirmed = false;
    }

    @EventSourcingHandler
    public void on(OrderConfirmedEvent event) {
        System.out.println(">>>>>> Handling OrderConfirmedEvent: " + this);
        orderConfirmed = true;
    }
}

После вызова конечной точки, как только я получаю этот журнал:

Calling COMMAND constructor
>>>>>> Handling OrderPlacedEvent: Order@3eecb9e2
Calling PARAMLESS constructor
>>>>>> Handling OrderPlacedEvent: Order@cd10277
>>>>>> Handling OrderConfirmedEvent: Order@cd10277

Как вы можете видеть OrderPlacedEvent вызывается дважды вместе с конструктором без параметров. Кто-нибудь знает, почему я испытываю следующее поведение?

1 Ответ

1 голос
/ 27 января 2020

Это поведение является правильным и ожидаемым, когда вы используете Event Sourcing. В Event Sourcing каждый раз, когда вы отправляете команду в агрегат, она сначала загружает все предыдущие события для гидратации агрегата и определения его текущего состояния. Эти события - ваш источник правды. Текущее состояние агрегата, за исключением некоторых исключений, не сохраняется.

Таким образом, в общем случае вам следует убедиться, что вы используете только EventSourcingHandler в агрегате для заполнения его состояния.

Обратите внимание, что, как только система сильно разрастется, в совокупности может появиться большое количество событий, которые необходимо будет прочитать. Если это произойдет, есть некоторая оптимизация, которую вы можете сделать, сохраняя снимок вашей совокупности (ее текущее состояние) после каждых n событий. Таким образом, вам не нужно загружать более n событий.

...