CQRS – Domain state

December 8th, 2009

This morning Aaron Jensen asked a really interesting question on Twitter “Should Aggregate Roots en Entities always keep their state if it is not needed for business decisions? Is firing events and relying on the reporting store enough?”. He really made me think, Aaron thanks for that!

So for example you have some behavior on your domain that gets called when a customer moves, this behavior will publish a Customer Moved event containing the new address. If the domain does not use the address information for any decision making, does it then need to be persisted in the aggregate root?

I guess it would greatly depend on whether or not you are using Event Sourcing to persist your published events (this is what I would suggest). If you do then I don’t see a problem in skipping storing the address information in the aggregate root. Because if at a later time you need the address information to make some decisions then it is easy to retrieve this from the events when reloading the aggregate root from the event store. You just create the address property and an internal event handler to process the Customer Moved event. Just make sure you delete the snapshots first.

But if you do not store all the events that you publish, but instead store only a snapshot then I would not skip storing the new address information, because in the end the domain is responsible for the state, not the reporting side. In other words, you can rebuild the reporting side from the domain, but you cannot necessarily do the same in reverse. So if you don’t store the address information and you need to rebuild the reporting store then you cannot do this.

So my conclusion is that the information should be available on the domain side. And when using CQRS and Event Sourcing to store the events instead of the internal state of the domain then that makes it possible to skip having the information in the domain structure, else not.

Mark Nijhof Architecture, CQRS, DDD

  1. December 9th, 2009 at 05:22 | #1

    Always nice to see people have similar ideas about some things. I’ve been asking myself the same question for a while now, and came to the same conclusion.

    That is, until I started implementing snapshot events. If you want to use snapshot events to limit the number of historical events to load, your aggregate will need to fully maintain its internal state.

  2. December 9th, 2009 at 07:23 | #2

    @Allard Buijze
    You would only keep one snapshot per AR, so if you change the internal state representation of the AR then just delete the snapshot and let something regenerate it again. (I have a blog post coming about that as well). You would be doing this for each type of change.

  3. December 9th, 2009 at 10:06 | #3

    @Mark Nijhof
    I am eager to read your next post. I’ve enjoyed the previous ones, anyway (although your C# code samples use constructs that we don’t have in Java ;-) )

    My idea was that the “something” that generates the snapshot event would be the domain object itself. In order to do that, it should know what (for example) the last known address was.

  4. December 9th, 2009 at 12:04 | #4

    @Allard Buijze
    Yuo are correct the domain generates the snapshot and is the only one that knows the structure. But you can savely delete them as any-time, that just means that now all the events will be loaded again. Now you would probably have a daemon in the background generating snapshots, so hopefully when the AR is needed you don’t actually need to load all events. (I’ll discuss this in more details in the next CQRS post).

  5. December 9th, 2009 at 20:55 | #5

    @Allard Buijze
    Snapshotting doesn’t change the need to persist the state in question in this post. We’re simply discussing state that is irrelevant to business logic. You wouldn’t need it ever, so no need to store it in the snapshot. The only place its needed is in reporting, and as such, that’s the only place it lives.

  6. Allard Buijze
    December 10th, 2009 at 01:26 | #6

    @Aaron Jensen
    Aaron, you caught me in a moment of “a snapshot captures full state” thoughts here. I probably didn’t get rid of all the “traditional” ways of thinking yet. You’ve got an absolutely valid point there. Thanks for that!

  7. December 10th, 2009 at 05:20 | #7

    @Aaron Jensen
    It looks like Udi is on the same line as you http://www.udidahan.com/2009/12/09/clarified-cqrs/comment-page-1/#comment-36874 saying that some information does not need to be in the domain model at all, independently of the way to build it. Meaning putting much more responsibilities on the reporting side then I imagined.

  8. Roy
    January 1st, 2010 at 06:34 | #8

    So your domain is basically in memory at all times. Meaning, none of your AR are disposed. You constantly add new ones in memory and save the state of those AR from time-to-time.

  9. January 1st, 2010 at 07:04 | #9

    @Roy
    I am not sure how you got that impression? The identity map determins how long an AR stays in memory, but that is not discussed in this post :)

  10. Roy
    January 1st, 2010 at 19:55 | #10

    I think the word “daemon” in the 3rd comment threw me off. To me, that means a background service. I was tring to make sense of why you would run a background service to commit a snapshot of an aggregate. I don’t think I understand the purpose of a snapshot. I was thinking that snapshots are only taken after a commit command is given by the client.

Comment pages
Comments are closed.