Axonframework: Axon 4 - Saga run again after JVM restart

Created on 1 Feb 2019  Â·  8Comments  Â·  Source: AxonFramework/AxonFramework

I am using Axon4 with Spring boot. Created simple saga. Its works well during JVM in flight. However once it restarts, it re-runs the Saga again.

Tried to to JpaSagaStore for persistance, did not work. Below are code snippet. Please help.

@Configuration
public class AxonConfig {

@PersistenceContext
private EntityManager entityManager;

@Bean
public SagaStore sagaStore() {
    return JpaSagaStore.builder().entityManagerProvider(new SimpleEntityManagerProvider(entityManager)).build();
}

}

@Saga(sagaStore = "sagaStore")
@Slf4j
public class OrderSaga {

@Autowired
private transient CommandGateway commandGateway;

private UUID orderId;

private boolean passed;

@StartSaga
@SagaEventHandler(associationProperty = "orderId")
public void on(OrderPlacedEvt evt) {
    log.debug("handling {}", evt);
    if (!passed) {
        orderId = evt.getOrderId();
        UUID shipmentId = UUID.randomUUID();
        associateWith("shipmentId", shipmentId.toString());
        commandGateway.send(new PrepareShipmentCmd(shipmentId, evt.getDestination()));
    }
}

@SagaEventHandler(associationProperty = "shipmentId")
public void on(ShipmentPreparedEvt evt) {
    log.debug("handling {}", evt);
    log.debug("orderId: {}", orderId);
    commandGateway.send(new RegisterShipmentForOrderPreparedCmd(orderId, evt.getShipmentId()));
}

@SagaEventHandler(associationProperty = "shipmentId")
@EndSaga
public void on(ShipmentArrivedEvt evt) {
    log.debug("handling {}", evt);
    log.debug("orderId: {}", orderId);
    commandGateway.send(new RegisterShipmentForOrderArrivedCmd(orderId, evt.getShipmentId()));
}

}

Question

Most helpful comment

Let me give you a little back ground first @pms-github.

A Saga instance will receive it's from an Event Processor.
The default Event Processor in Axon 4 is the TrackingEventProcessor - this will keep track of which events it has handled. This allows you to start and stop your application, without events being handled a new, as well as enabling replays for your Query Model.
The TrackingEventProcessor for this 'keeps track' of which events it has handled in a TrackingToken, which is stored in a TokenStore.

My hunch is that you're using an InMemoryTokenStore - this means that on every restart, the TrackingEventProcessor used to provide events to your saga will start from the beginning of time.
Thus to resolve this you should ensure that the application running your Saga has a database to store tokens in.

Lastly, I'll be closing this as a 'Question', and would like to note that typically questions are meant for the Axon Framework User Group or for Stack Overflow (with the tag axon).

All 8 comments

Let me give you a little back ground first @pms-github.

A Saga instance will receive it's from an Event Processor.
The default Event Processor in Axon 4 is the TrackingEventProcessor - this will keep track of which events it has handled. This allows you to start and stop your application, without events being handled a new, as well as enabling replays for your Query Model.
The TrackingEventProcessor for this 'keeps track' of which events it has handled in a TrackingToken, which is stored in a TokenStore.

My hunch is that you're using an InMemoryTokenStore - this means that on every restart, the TrackingEventProcessor used to provide events to your saga will start from the beginning of time.
Thus to resolve this you should ensure that the application running your Saga has a database to store tokens in.

Lastly, I'll be closing this as a 'Question', and would like to note that typically questions are meant for the Axon Framework User Group or for Stack Overflow (with the tag axon).

I got that but somehow not able to configure JPA persistant store properly. If you can help me with the ideal configuration to achieve persistant axon saga would be great :). Below is the configuration I tried.

@configuration
public class AxonConfig {
@PersistenceContext
private EntityManager entityManager;

@Bean
public SagaStore sagaStore() {
return JpaSagaStore.builder().entityManagerProvider(new SimpleEntityManagerProvider(entityManager)).build();
}

Do you use Spring Data JPA or configure JPA ‘manually’?

Spring data JPA

Then you should have the JPA TokenStore by default. Are you using an embedded database?

I am using Postgres database and default axon server docker image.

DB conf -

spring.datasource.username=orderdemo
spring.datasource.password=secret
spring.datasource.driver-class-name=org.postgresql.Driver

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL95Dialect
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.hbm2ddl.auto=create
spring.jpa.properties.hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.properties.hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

On Fri, Feb 1, 2019, 8:09 PM Allard Buijze <[email protected] wrote:

Then you should have the JPA TokenStore by default. Are you using an
embedded database?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/AxonFramework/AxonFramework/issues/983#issuecomment-459743392,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ARJtuzuY0TSii7UUzGpzyaNAO2gO9Bf-ks5vJFGSgaJpZM4adqiz
.

The line
spring.jpa.properties.hibernate.hbm2ddl.auto=create
is the problem. create means that the database is cleared from any data on startup. Since AxonServer will still contain its events, the application is made to believe it has a lot of catching up to do.
You probably want
spring.jpa.properties.hibernate.hbm2ddl.auto=update
which creates tables if they don't exist, and will create columns if entities declare attributes that can't be mapped to existing ones.

It was freak mistake under my nose ! its working now with spring.jpa.properties.hibernate.hbm2ddl.auto=update , thank you !
Cheers

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bliessens picture bliessens  Â·  3Comments

tunovic picture tunovic  Â·  5Comments

wangshihui picture wangshihui  Â·  4Comments

m1l4n54v1c picture m1l4n54v1c  Â·  4Comments

dmurat picture dmurat  Â·  5Comments