Load (old) Aggregate in a specific (older) version

Hi everybody!

I already found this old thread for my problem:
https://groups.google.com/forum/#!searchin/axonframework/historic$20aggregate|sort:date/axonframework/FLtWkNcBnnc/0bNpZ0LaDQAJ

If I get it right, the answer was more or less: Use a read model to get access to old aggregate versions.
Since I’m doing a lot of writes but only very rare reads on the aggregate, I would prefere to simply read the aggregate from the event-stream
up to the requested version.

But I think it is still not possible in Axon 3 to retrieve an aggregate in a specific version, right?
When looking at the EventSourcingRepository, I got a method

protected EventSourcedAggregate<T> doLoadWithLock(String aggregateIdentifier, Long expectedVersion) {

But the expectedVersion isn’t used at all there.
Wouldn’t it be useful to be able to retrieve old versions of an aggregate without the io-overhead of creating a separte read-model?

Hi Dirk,

I’d argue it might just be very worthwhile to have functionality like that in place, yes.

As always, you’re free to open up an issue on the Axon Framework GitHub page; that’ll help for our discussion when and if to pick this up.

A part from that, the API luckily allows you to provide an expected aggregate version, although you’ve correctly noted it is not being used.
A personal Repository implementation which does leverage the expected aggregate version should thus not be to hard to achieve.

It is typically the case however that you’d only retrieve an aggregate to perform commands on it.

Taking that stance, I’d assume that performing commands on old aggregates doesn’t seem like a very likely use case.

That is very likely the reason why the post you’re referring too states that if you’re querying old aggregates, that you should introduce a query model for that.

Hope this gives you some insights Dirk.

Cheers,
Steven

Hi Dirk,

I’d like to add a small nuance to my reply earlier.

I stated that the expectedVersion isn’t used by the EventSourcingRepository.

Although it holds that the EventSourcingRepository#doLoadWithLock(String aggregateIdentifier, Long expectedVersion) function currently does not use the latter parameter, it is not true that the EventSourcingRepository isn’t using the expectedVersion entirely.

The expected version is used to after loading an Aggregate from the Repository, in the validateOnLoad(Aggregate<T> aggregate, Long expectedVersion) function.
This validate action (although I haven’t been able to 100% ‘validate’ this) used to be part of the doLoadWithLock(String, Long) function, hence why it remained a part of the API.

Hope this provides some extra clarification for you.

Cheers,
Steven

Thanks for your hints Steven!

I introduced a “VersionedEventStore” with a new method:

public interface VersionedEventStore extends EventStore {

   DomainEventStream readEventsUpToSpecificVersion(String aggregateIdentifier, long specificVersion);
}

It works fine. Now you could do something like:

verteilOrganisationAggregate = versionedRepository.loadSpecificVersion(command.getVerteilOrgaId(), command.getVersion());

and then simply return the aggregate with an historic state. I think this is pretty powerful.
The overhead to save all versions of the aggregate in a separate read model would have a huge io and memory impact.

If you like this feature to get into the framework, I could provide a PR for it.

Hi, Can you share your implementation with me ? I’m doing something similar but it seem hard to me

在 2018年6月1日星期五 UTC+8下午8:52:10,Herr Manns写道: