State-stored aggregate pollutes domain model with persistence concern

Hi there,

I was browsing through the Axon Reference Guide when I read the section about state-stored aggregates [1], which contains the following code example:

`
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.modelling.command.AggregateMember;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

@Entity
public class GiftCard {

@Id
@AggregateIdentifier
private String id;

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = “giftCardId”)
@AggregateMember
private List transactions = new ArrayList<>();
/* rest of example truncated */
}
`

Depending on those javax.persistence annotations is reintroducing an infrastructure concern (persistence) into the domain model and mixing it with the data model, precisely the thing we’re trying to avoid with DDD. This example is also failing to uphold Axon’s own principle of “separating business from infrastructure” [2]. Isn’t there a way of using state-stored aggregates with Axon that separates the domain model from the data model?

I already feel uncomfortable at having framework annotations (Spring or Axon) in my domain model classes, but this is pushing it too far. :frowning:

Cheers,
Etienne

[1] https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/state-stored-aggregates
[2] https://axoniq.io/resources/axon-core-principles

My understanding is that state-stored aggregates are provided for users who don’t want to adopt event sourcing and indeed want to persist their aggregates using a traditional ORM approach.

If you are uncomfortable with using state-stored aggregates, Axon provides event-sourced aggregates:

https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/aggregate

Using event-sourcing allows you to completely decouple your domain model from persistence concerns - modulo the event serialisation mechanism you use.

Using event-sourcing allows you to completely decouple your domain model from persistence concerns - modulo the event serialisation mechanism you use.

I understand that event-sourcing is Axon’s preferred storage style and has advantages over storing state. However, decoupling persistence isn’t really a property of event-sourcing, this is the Repository’s job, IIRC.

I still lament the fact that a framework who champions DDD publishes such a contradicting example.

Etienne

Hi Etienne,

We indeed advocate DDD (just as well as EDA, CQRS and Event Sourcing) as a prime solution when it comes to building software.
Part of our motto has been the pragmatic approach towards this, to not have theory block the users too much.
This ushered the use of annotations as such a beneficator, even though it is not inline with some people their view points…

We do know that from the “DDD purist” standpoint, this is a massive no-no, and as such we are having internal talks to come up with a configuration model which will allow you to draft up the domain model entirely without Axon specifics.
Having said that, there is no timing when this will be introduced, although a personal hunch would state “Axon 5”.

I’d thus like to apologize to you for not being able to provide a “framework free domain model” right now.
Hope you understand, and know that we are working on it behind the scenes.

Kind regards,

Steven van Beelen

Axon Framework Lead Developer

AxonIQ

twitter-icon_128x128.png