Axon Framework Event Package Refactoring

373 Views Asked by At

I have a set of events that have been refactored to another package. This works as is until I execute the event replay. Digging deeper I noticed a payloadtype in the domainevententry table and figure changing this would be sufficient but alas it seems the xml root element of the event needs to be changed as well. I am hoping there is a simple way to do this.

I cannot find any examples on upcasting to different packages or using XStream aliasing so any help would be greatly appreciated.

Thanks

2

There are 2 best solutions below

2
Steven On BEST ANSWER

As you noticed, the default payload type stored in events is the fully qualified class name. This ensures that out of the box serialization and deserialization work as intended. However, moving classes around thus means the payload type can no longer be found, requiring some adjustment to be made.

You could have used the EventTypeUpcaster, as referred to in the Reference Guide. The EventTypeUpcaster is dedicated to adjusting the payload type, and thus can also be used to deal with changing package names.

When using (the default) XStreamSerializer, aliasing the tags would indeed also work. How to set aliases can be seen here for example. AS noticed in that sample, the alias is added to the XStream instance. The XStreamSerializer uses an XStream instance to support de-/serialization from/to XML. To adjust the XStream instance, you can simply use the builder paradigm on the XStreamSerializer. The JavaDoc of the builder should be specific enough to help you out how to use it.

0
Kenneth Clark On

Went the long way round with this but it seems to work. As always, backup your database before executing large volume changes. I also restarted the service using the database on completion. Needless to say I will make sure the events are in logical packages before deploying next time :)

Database Engine: Postgres 10

Table: domainevententry

    update domainevententry
    set
        payloadtype = '<new.package.Classname>',
        payload = lo_from_bytea(0, decode(REPLACE(
            subquery.output,
            '<old.package.Classname>',
            '<new.package.Classname>'
            ), 'escape'))
    from (
        SELECT eventidentifier, payloadtype, encode(lo_get(payload::oid), 'escape') as output FROM domainevententry
        WHERE eventidentifier in (
            '<event guid 1>',
            '<event guid 2>'
        )
        AND payloadtype = '<old.package.Classname>'
    ) as subquery
    where domainevententry.eventidentifier = subquery.eventidentifier;

Once that is completed I needed to update the OWNER of the large object:

ALTER LARGE OBJECT <LargeObjectId> OWNER TO database_role;

Probably not the most elegant solution but based on the time constraints I have, it did the job. There are probably encoding issues with this solution for the large object but it all worked out for me in the end. Feel free to share any optimizations that would make the above more suitable.

Firing off the Axon Framework replays rebuilt the projections and everything lined up.