Entity Polymorphism


i want to have an aggregate (ProductionPlan) with a list of entities (ProductionSteps).

private Map<String, ProductionStep> productionSteps;

ProductionStep is of course an entity.

public class ProductionStep {

	protected String productionStepId;

//Some more

Now in my system there are different productionSteps which use different attributes. Also they have different CommandHandler.
Is there a possibility to use polymorphism in entities? Something like:

public class Coloring extends ProductionStep {

	private Pigment color;

At the moment i get the following exception from my application if i call a commandhandler which is handled in “Coloring”

org.axonframework.commandhandling.NoHandlerForCommandException: No Handler for command: ProductionPlanAPI$ChangeColorOfColoringCmd

Hello @Kai_lfkr and welcome to the forum!

The answer to your question is short and simple: no you cannot.
Axon’s annotation logic does not validate all the existing implementations of generic types on collections or maps. To be able to support this based on reflection and annotation scanning, we’d have to adjust the annotation or provide additional annotations so that the user (you in the case) can specify what the parent and children of the class are.

As this effort is none trivial to implement, but fairly easily dealt with in your aggregate by adding separate collections, we opted to not yet implement this in AF.
Note I’m saying “not yet” there. As time moves on, our priorities change, of course.

However, for now, it’s best if you add separate collections for every version of this ProductionStep.
I hope that clarifies things for you, @Kai_lfkr!

I was wondering: There most certainly is a finite amount of different production steps.
If JDK 17 and above is used, maybe you could use sealed classes / interfaces (JEP 409: Sealed Classes) for your ProductionStep entity. See an example here: Sealed Classes and Interfaces in Java 15 | Baeldung.

Eventually Axon Framework has to be extended for this, but instead of residing to class scanning, it is probably be possible to find all implementations via reflection then.