question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

"Polymorphic Aggregates in Spring" documentation (and error-handling) lacking

See original GitHub issue

Basic information

  • Axon Framework version: 4.4.3
  • JDK version: openjdk version “11.0.3” 2019-04-16 LTS

Documentation says:

Polymorphic Aggregates in Spring If you are using Spring, Axon will automatically detect polymorphic aggregates based on the @Aggregate annotations and class hierarchy. The @Aggregate annotation needs to be put on the shared parent class that contains the aggregate identifier, as well as every subclass that is a potential instance type of that shared parent class.

I’ve read that as

This worked so far, but we didn’t really do much with polymorphic aggregates. Now consider this:

@Aggregate
abstract class A {
    @AggregateIdentifier String id;
}

// no annotation here as per my understanding of the docs
abstract class B extends A {
}

@Aggregate
class C extends B {
}

Generally this works. Unless you attempt to call a command-handler in B. I don’t have it in front of me right now, but IIRC in SpringPrototypeAggregateFactory.afterPropertiesSet/AbstractAggregateFactory.postProcessInstance() the lookup subtypes.get(aggregate.getClass()) looks for B.class here which is not contained in the map and the result is a rather meaningless NPE. You are doing a fine job with error messages all over the place and I feel SpringPrototypeAggregateFactory can be improved a bit here. 😃

Second there is the documentation. Again as I’ve read it, the example above should work, but doesn’t. It can be fixed by adding @Aggregate to B, but is it the right way?

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
michaelbubcommented, Mar 29, 2022

What we did wrong:

In the early days (already Axon 4.x, but not sure which) we setup AspectJ to provide logging for each type of handler (Command/Event/Query). During development it became clear that Axon does not like if someone else is messing with the Aggregate classes. I remember the error we got made it rather obvious that whatever AspectJ does to the class, the change of type to generated proxy class, did not work with Axon. So we excluded handlers in aggregates from AspectJ, i. e. we excluded all handlers in classes with the @Aggregate annotation. Then polymorphism came along and suddenly there are command handlers in (abstract) aggregates that don’t have the annotation. Boom! Only this time the error is far less obvious. So by adding the annotation to B I was merely disabling AspectJ again, making everything work as it should have in the first place.

Now as we know Axon a little bit better there are probably better ways to do logging in just the same way. MessageXInterceptor classes should do the trick.

I am closing this as it’s most certainly not a bug in Axon.

0reactions
smcvbcommented, Mar 29, 2022

Wow darn, that’s a pretty massive gotcha there, @michaelbub. Thanks for sharing that with us!

If at all applicable, I’ll see if future versions of the Framework can coop better with stuff like AspectJ. Or, at least, provide more precise guidance on the subject through the Reference Guide or exception messages.

Thanks again for sharing this with the community, @michaelbub.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Spring Data MongoDB - Reference Documentation
As of Spring Data 2.0, repository CRUD methods that return an individual aggregate instance use Java 8's Optional to indicate the potential absence...
Read more >
How to use polymorphic associations with Spring Data REST
I was looking for a specific solution for SDR without using controllers but just repositories (that later SDR converts in controllers/endpoints) ...
Read more >
Releases · AxonFramework/AxonFramework - GitHub
[#2473] Ensure lifecycle handlers for components declared as Spring beans are ... of polymorphic aggregates cause IncompatibleAggregateException #2464 ...
Read more >
Spring Boot and Java Tutorial: Build a CRUD API - Auth0
Learn how to use Spring and Java to build a feature-complete API. ... go through the list of dependencies and download the missing...
Read more >
OpenAPI 3 Library for spring-boot
Automatically generates documentation in JSON/YAML and HTML format APIs. This documentation can be completed by comments using swagger-api ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found