Polymorphic Aggregate Migration
Polymorphic aggregates allow you to define a hierarchy where subtypes inherit command and event sourcing handlers from their superclasses. For a detailed guide on how to model these, please refer to the modeling section.
Let’s take a look at the following example:
public abstract class Card {}
public class GiftCard extends Card {}
public class OpenLoopGiftCard extends GiftCard {}
public class RechargeableGiftCard extends GiftCard {}
In Axon Framework 4, polymorphic aggregates were often configured using Spring’s @Aggregate annotation on both the base and subclasses.
When using the manual configuration API, you would use AggregateConfigurer.
In Axon Framework 5, you register the hierarchy through the EventSourcingConfigurer.
-
Axon Framework 5 (Declarative)
-
Axon Framework 5 (AutoDetected)
-
Axon Framework 4
public class AxonConfig {
// ...
public void configure(EventSourcingConfigurer configurer) {
configurer.registerEntity(
EventSourcedEntityModule.declarative(String.class, GiftCard.class)
.messagingModel((configuration, builder) -> PolymorphicEntityMetamodel.forSuperType(GiftCard.class)
.addConcreteType(AnnotatedEntityMetamodel.forConcreteType(
OpenLoopGiftCard.class,
configuration.getComponent(ParameterResolverFactory.class),
configuration.getComponent(MessageTypeResolver.class),
configuration.getComponent(MessageConverter.class),
configuration.getComponent(EventConverter.class)
))
.addConcreteType(AnnotatedEntityMetamodel.forConcreteType(
RechargeableGiftCard.class,
configuration.getComponent(ParameterResolverFactory.class),
configuration.getComponent(MessageTypeResolver.class),
configuration.getComponent(MessageConverter.class),
configuration.getComponent(EventConverter.class)
))
.build())
);
// other phases (factory, etc.) omitted for brevity
}
}
In most cases, you can rely on auto-detection of polymorphic entities by Axon Framework 5. Simply register the base type, and the framework will discover the subtypes automatically.
@EventSourcedEntity(
concreteTypes = {
OpenLoopGiftCard.class,
RechargeableGiftCard.class
}
)
public class GiftCard extends Card {
// ...
}
public class AxonConfig {
// ...
public void configure(EventSourcingConfigurer configurer) {
configurer.registerEntity(
EventSourcedEntityModule.autodetected(String.class, GiftCard.class)
);
}
}
public class AxonConfig {
// ...
public void configure(Configurer configurer) {
Set<Class<? extends GiftCard>> subtypes = Set.of(
OpenLoopGiftCard.class,
RechargeableGiftCard.class
);
configurer.configureAggregate(
AggregateConfigurer.defaultConfiguration(GiftCard.class)
.withSubtypes(subtypes)
);
}
}