Always get old value when load from EventSourcingRepository

Hi,

I’m trying to reach a simple product reservation scenario when a order is created.
When handling a ReserveProductCommand, I need to load the latest product information to check whether if the stock is enough to reserve.

`

Aggregate aggregate = repository.load(command.getProductId());
aggregate.execute(aggregateRoot->aggregateRoot.reserve(command.getOrderId(), command.getNumber()));

`

`

public void reserve(OrderId orderId, int amount){
if(stock>=amount) {
int oStock = stock;
stock = stock - amount;
apply(new ProductReservedEvent(orderId, id, stock));
LOGGER.info(“Product [{}] stock changes {} → {}”, id, oStock, stock);
}else
apply(new ProductNotEnoughEvent(orderId, id));
}

`

I use mongodb as the EventStore, and the event are as below

`

db.domainevents.find({“type”:“ProductAggregate”}).pretty()
{
“_id” : ObjectId(“58d4e5aa73bc0c0f745619ae”),
“aggregateIdentifier” : “1”,
“type” : “ProductAggregate”,
“sequenceNumber” : NumberLong(0),
“serializedPayload” : “{"id":"1","name":"ttt","price":1000,"stock":100}”,
“timestamp” : “2017-03-24T09:23:54.101Z”,
“payloadType” : “com.edi.learn.axon.common.events.ProductCreatedEvent”,
“payloadRevision” : null,
“serializedMetaData” : “{"traceId":"9a8ea7a6-8825-4dc2-8451-45e900e14f94","correlationId":"9a8ea7a6-8825-4dc2-8451-45e900e14f94"}”,
“eventIdentifier” : “d6c90144-7320-46f7-9c63-c5a3c5d63bcf”
}
{
“_id” : ObjectId(“58d4e5fe73bc0c0f745619b0”),
“aggregateIdentifier” : “1”,
“type” : “ProductAggregate”,
“sequenceNumber” : NumberLong(1),
“serializedPayload” : “{"orderId":{"identifier":"18e18a59-2313-4908-bff6-ce20f40ae2a1"},"productId":"1","amount":10}”,
“timestamp” : “2017-03-24T09:25:18.310Z”,
“payloadType” : “com.edi.learn.axon.common.events.ProductReservedEvent”,
“payloadRevision” : null,
“serializedMetaData” : “{"traceId":"c67e86d8-3964-496c-b6cd-1e2552a9dae8","correlationId":"c67e86d8-3964-496c-b6cd-1e2552a9dae8"}”,
“eventIdentifier” : “46c28d7b-dda2-43e7-981a-0e31871f5516”
}
{
“_id” : ObjectId(“58d4e63f73bc0c0f745619b3”),
“aggregateIdentifier” : “1”,
“type” : “ProductAggregate”,
“sequenceNumber” : NumberLong(2),
“serializedPayload” : “{"orderId":{"identifier":"1786d799-aa4b-472a-ba17-87416b52ad43"},"productId":"1","amount":10}”,
“timestamp” : “2017-03-24T09:26:23.334Z”,
“payloadType” : “com.edi.learn.axon.common.events.ProductReservedEvent”,
“payloadRevision” : null,
“serializedMetaData” : “{"traceId":"6e541c61-b367-4503-b9ee-fa120a3626cc","correlationId":"6e541c61-b367-4503-b9ee-fa120a3626cc"}”,
“eventIdentifier” : “0fec7b33-b38a-4d23-811e-6baf95cd27df”
}

`

The method runs correctly, but the aggregate state is not updated. It always return the original stock number.

Can anyone help?

Thanks,

Hello Edison,

When the aggregate is loaded from the repository all events are played again. (Not the commands…)
So if you want to change the state of the aggregate you should do that in the handler of the ProductReservedEvent.

Hope it helps :slight_smile:

Frank

Hi Frank,

Thanks for clarification. Yes, you’re right, I totally forgot this and naturally went to the “method invoke” way.

public void reserve(OrderId orderId, int amount){
    if(stock>=amount) {
        apply(new ProductReservedEvent(orderId, id, amount));

    }else
        apply(new ProductNotEnoughEvent(orderId, id));
}

public void cancellReserve(OrderId orderId, int amount){
    apply(new ReserveCancelledEvent(orderId, id, stock));
}

@EventHandler
public void on(ProductReservedEvent event){
    int oriStock = stock;
    stock = stock - event.getAmount();
    LOGGER.info("Product {} stock change {} -> {}", id, oriStock, stock);
}

@EventHandler
public void on(ReserveCancelledEvent event){
    stock +=event.getAmount();
    LOGGER.info("Reservation rollback, product {} stock changed to {}", id, stock);
}

After adding EventHandler on the aggregate, it works perfectly now.

在 2017年3月24日星期五 UTC+8下午5:55:53,Frank Groot写道: