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()));
}
}
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).
@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
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
TrackingEventProcessorfor this 'keeps track' of which events it has handled in aTrackingToken, which is stored in aTokenStore.My hunch is that you're using an
InMemoryTokenStore- this means that on every restart, theTrackingEventProcessorused 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).