I’m trying to find a way to, given an event store, provides the aggregate from id and sequence number;
Does anyone have idea how to help us do that?
I’m trying to find a way to, given an event store, provides the aggregate from id and sequence number;
Does anyone have idea how to help us do that?
Hi Lorenzo: This is be possible using the EventSourcingRepository API:
https://apidocs.axoniq.io/4.6/org/axonframework/eventsourcing/EventSourcingRepository.html
You can pass the eventStore to the Repository builder
val repo = EventSourcingRepository
.builder(YOUR_AGGREGATE::class.java)
//.parameterResolverFactory(parameterResolverFactory)
.eventStore(eventStore)
.build()
and then load the aggregateInstance via
val aggregate = repo.load(identifier)
Note that though this is technically possible, you should keep in mind CQRS, which means that on the command side you probably will seldomly deal with this configuration yourself because the registered aggregate will handle commands and state automatically, and on the read side you will create custom projections based on events.
Hi this is what i’ve been testing.
I expected to get the AccountAggregate loaded until version spacified … but i receive always the last version.
public class AccountQueryServiceImpl implements AccountQueryService {
private final EventStore eventStore;
private UnitOfWork<?> unitOfWork;
private AccountRepository accountRepository;
private EventSourcingRepository<AccountAggregate> testSubject;
.....
@Override
public AccountQueryEntity getAccount(String accountNumber, Long sequenceNumber) {
if (sequenceNumber == null) {
return accountRepository.findById(accountNumber).get();
}
unitOfWork = DefaultUnitOfWork.startAndGet(null);
testSubject = EventSourcingRepository
.builder(AccountAggregate.class)
//.parameterResolverFactory(parameterResolverFactory)
.eventStore(eventStore)
.filterByAggregateType()
.build();
Object aggregate = testSubject.load(accountNumber, sequenceNumber).getWrappedAggregate().getAggregateRoot();
Is there a way to load the Aggregate “state” passing id and axonSeqeunenceNumber ?
I’m trying to do the same thing using Axon Framework 4.8.0, but without success. I also can’t find documentation or examples on how to achieve this. So I’m wondering if anyone was able to do this?
I’ve debugged the internal code of Axon, and it seems that the expectedVersion
argument in Repository.load(String aggregateIdentifier, Long expectedVersion)
is never actually being used to limit the stream of domain events.
The way I’ve tested it (and didn’t work) was:
var message = new GenericMessage(...);
var unitOfWork = DefaultUnitOfWork.startAndGet(message);
var personAggregate = personEventSourcingRepository.load(id, sequence);
personAggregate.execute(p -> {
log.info("At this point I incorrectly get the latest version");
});
// Statement below also returns the latest version incorrectly
var person = personAggregate.getWrappedAggregate().getAggregateRoot();
Edit:
It seems this question was asked a long time ago, with a proposal implementation to add support to the framework. But there was no further reply
Hey @Bridge98 and @Pieter-Jan_Savat,
As you’ve found out, there’s no means to retrieve an Aggregate and limit how far you want it to load events with Axon Framework’s automatically provided components.
To be able to do so, you would be required to retrieve the event stream for a specific aggregate from the EventStore
directly, create the empty aggregate instance manually, and invoke every applicable event sourcing handler for the events within the stream up to and until the sequenceIdentifier
you want to load.
Mind you, doable (the above steps should get you there), but not default support from Axon Framework at this stage. If you do go this route, be sure to traverse Axon Framework’s code base and ask questions on the forum
Concerning this line specific from you, @Pieter-Jan_Savat:
The expectedVersion
field is filled by Axon Framework whenever you use the @TargetAggregateVersion
annotation on a field in the command you dispatch. This can be used to “tell” AF that “I expect the model to be at this position, and no further.”
In short, it’s not something that provides you with the functionality you’re looking for.
I hope the above helps both of you a little further!
Besides this, would you mind sharing with me/us why you’re looking for this functionality exactly?
Knowing the use cases helps me to deduce the priority for new functionality we add to Axon Framework.
Thanks in advance!