axon 3.1.1 - upcasting in spring boot - how to register

Hi

I need to upcast a PlayerCreated event in my spring boot axon application.

The original event did not have a @Revision annotation, so the revisionNumber is “null”.

I register a bean (kotlin):

private fun playerCreated(revision: String?) = SimpleSerializedType("d.h.r.PlayerCreated", revision)

@Bean

fun playerCreatedNullTo2() = object : SingleEventUpcaster() {
  override fun canUpcast(ir: IntermediateEventRepresentation): Boolean {
    return playerCreated(null) == ir
  }

  override fun doUpcast(ir: IntermediateEventRepresentation): IntermediateEventRepresentation {
    return ir.upcastPayload(playerCreated("2"), PlayerCreated::class.java, { createNewEvent })
  }
}

However, the Upcaster is not used.
In the docs I read that must provide a custom  JpaEventStorageEngine bean and set the upcaster.
I am using the axon-spring-boot-starter, so I do not define this bean, and I'd rather stick to the default implementation.

You must provide a custom JpaEventStorageEngine such as:

@Bean
JpaEventStorageEngine eventStorageEngine(Serializer serializer,
DataSource dataSource,
EventUpcaster upcasterChain,
EntityManagerProvider entityManagerProvider,
TransactionManager transactionManager) throws SQLException
{
return new JpaEventStorageEngine(serializer,
upcasterChain,
dataSource,
entityManagerProvider,
transactionManager);
}

where the EventUpcaster is an a EventUpcasterChain which is built by autowiring a list of upcasters available in your class path (you can also of course hardcode the list)

@Bean
EventUpcaster upcasterChain(@Autowired Optional<List> upcasters)
{
EventUpcasterChain eventUpcasterChain
if (upcasters.isPresent())
{
eventUpcasterChain = new EventUpcasterChain(upcasters.get());
}
else
{
eventUpcasterChain = new EventUpcasterChain(Collections.emptyList());
}
return eventUpcasterChain;
}

The error you make is that you verify again ir you have to verify again ir.type

@Bean

fun playerCreatedNullTo2() = object : SingleEventUpcaster() {
  override fun canUpcast(ir: IntermediateEventRepresentation): Boolean {
    return playerCreated(null) == ir.type // << THIS SHOULD SOLVE IT
  }

  override fun doUpcast(ir: IntermediateEventRepresentation): IntermediateEventRepresentation {
    return ir.upcastPayload(playerCreated("2"), PlayerCreated::class.java, { createNewEvent })
  }
}

Hi,

Sorry to hijack this post. Can I use MongoEventStoreEngine instead of JpaEventStoreEngine?
I have written the following method to upcast events in mongoDB. But it seems that it does not work. Nothing happens. I don’t find the doUpcast() method is run.

EventStorageEngine eventStorageEngine = new MongoEventStorageEngine(new XStreamSerializer(),
        userEventUpcaster,
        new DefaultMongoTemplate(client),
        new DocumentPerEventStorageStrategy());

Hi Polly,

I am not entirely sure what you’re aiming for with your question under this post.
Regardless, let me try to help you out.

Can I use MongoEventStoreEngine instead of JpaEventStoreEngine?

Yes you can. You can specify the EventStorageEngine used by building the EmbeddedEventStore with the desired EventStorageEngine by using the EmbeddedEventStore.Builder#storageEngine(EventStorageEngine) function, or by simply providing a bean of the desired EventStorageEngine if you’re in a Spring Boot context.

I have written the following method to upcast events in mongoDB.
I think you’re having a misconception on the concept upcasting.
I’d like to reference you to the Reference Guide regarding upcasting events.

If you want to migrate events from a JPA store to a MongoDb store, that would be an effort you’d have to perform yourself.
Do note though that we typically suggest against using MongoDb as your event storage engine, as we’ve noted strange behavior regarding it with relative frequency.
Other options you’d have would be Axon Server, or the JpaEventStorageEngine and JdbcEventStorageEngine.

Hope this helps you out!

Cheers,
Steven