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?
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.
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.
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…
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.
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.
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.
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.