Aggregate versions

Hi,

i’m stumbled upon a problem while trying to implement a simple prototype with Axon. I’ve made a read/view model that updates on domain events.
This model needs to keep track of the current aggregate version. How would i pass the aggregate version information to the read/view model?. I can’t propagate it via the events itself
as the aggregate version is incremented even after event creation when applying it to the domain model itself. Should i use the GenericEventMessage optionally passed to my read/view models event handling?
There is a getSequenceNumber() method on it which may be equal to the current aggregate version. Is this the suggested method in this case?

Thanks

Marcus

Hi Marcus,

you can add an optional parameter of type EventMessage (don’t use GenericEventMessage). On this message, you can get the sequence number of an event.
As of Axon 2.1, you can add a parameter of type long and annotate it with @SequenceNumber.

Kind regards,

Allard

Hi Allard,

thanks for explanation. I wonder whether the sequenceNumber is always equal to the aggregate version. Maybe it must be passed separately in Axon 2.1?

Regards

Marcus

Hi Marcus,

for event sourced aggregates, the version is always that same as the sequence number of the last event.
“Regular” aggregates update the version each time they’re stored.

Cheers,

Allard

OK. I understand. However, saying this it raises another question to me. What if a command produces multiple events? Should’nt the version be incremented only once in that case? Otherwise it needs to pass back the resulting version back to the client right after command processing to avoid subsequently version conflicts. Sorry for asking noob questions…

Hi Marcus,

if a command processes multiple events, it’s still the last event applies that defines the version of an aggregate. So if your apply 3 events to version 5, the new version if 8. Versions 6 and 7 have never existed.

If a handler is interested in an aggregate’s version, it should listen to all events generated by that aggregate to know its real version.

Cheers,

Allard

Thanks for your patience Allard. My next question will be asked on a separate thread :wink:

Regards

Marcus

Hi Allard,

while playing around with aggregate versions i found the following code in AbstractRepository:

protected void validateOnLoad(T aggregate, Long expectedVersion) {
if (expectedVersion != null && aggregate.getVersion() != null && aggregate.getVersion() > expectedVersion) {
throw new ConflictingAggregateVersionException(aggregate.getIdentifier(),
expectedVersion,
aggregate.getVersion());
}
}

Shouldn’t the ConflictingAggregateVersionException be thrown when aggregate.getVersion() != expectedVersion? At least the source comment at repository.load() says so.
So the check seems wrong to me as a bad client will ever win if it chooses a very high version number.

Cheers

Marcus

Hi Marcus,

it’s a theoretical case, but it seems true that according to documentation, a “!=” is expected, instead of a “>”. In practice, clients don’t “choose” a version number, they receive one. If they choose an arbitrary value, then the behavior is arbitrary as well.

You’re welcome to send a pull request :wink:

Cheers,

Allard

Hi Allard,

sorry for bother you but i doubt that its only a theoretical problem. We plan to build a REST interface to our domain where the client isn’t under our control. So a maybe buggy client will win any concurrent modifications.
So if there is no real reason to check not for equality i will create an issue and file a tiny pull request.

Regards

Marcus

it’s not really “winning”. It’s just not getting an exception notifying you that the version you’re expecting isn’t the one you get.

But it should be fixed…