Hey Marc,
we’ve resolved our huge relationships to linked @Aggregates managing their relationships (your option 1) and are quite satisfied with that. Our main reason to do so was to keep the number of events per aggregate instance as low as possible for performance reasons - so now we’ve sliced our domain such that our aggregate instances have some 100 events over their lifetime in total.
The biggest challenge for us was to keep the command model consistent when creating entities and executing cascade operations. We have a 4-layered hierarchy in our domain model, each entity is modeled as separate aggregate managing the relationship with it’s parent by storing the id of the parent:
We solved creating by running the create command of a child via the parent aggregate (to validate the parent exists) but from there only sending a create command to the child aggregate without having any event published in the parent - so we can be sure the parent exists during creation.
For cascading operations (e.g. deleting a tree starting from a parent) we keep a command model that reflects the relationships (a flat domainEntity table having ids and parentIds) and iterate it to cascade commands down through the entity tree.
You can also find a discussion on cascade operations here: https://groups.google.com/g/axonframework/c/860POX06EiQ
Best Regards,
Jakob