AggregateDeletedException if markDeleted inside @EventHandler

We have an AbstractAnnotatedAggregateRoot, under some circumstances it expires and should be cancelled.
So the aggregate has this methods:

`

public void expire() {
apply(new MyAggregateNameExpiredEvent(aggregateId));
}

@EventHandler
public void handle(final MyAggregateNameExpiredEvent event) {
markDeleted();
}

`

but in Unit testing I got the following exception:

`
org.axonframework.eventsourcing.AggregateDeletedException: Aggregate with identifier [da027fcd-aef0-4771-80b2-02bf1afd243b] not found. It has been deleted.

`

Why I get this? is it not allowed to markDeleted() inside an @EventHandler, if so how to close the aggregate?

Thanks

Hello Pietro,

Can you post the actual test?

As far as I can tell you can only get this exception if you try to load a deleted aggregate. And while I’m no expert on idiomatic axon usage, but from the code alone I can see no reason why it should throw that exception.

I have tried to recreated your problem with a simple test case and it works for me, so again we need to see your actual test case in order to see were things seem to go wrong.

Cheers,
Paul

Thank for your reply, here my Test:

`

private FixtureConfiguration fixture;

@Mock
private ClaimedUserNameRepository claimedUserNameRepository;

@Before

public void setUp() {
MockitoAnnotations.initMocks(this);

fixture = Fixtures.newGivenWhenThenFixture(MyAggregate.class);

final MyAggregateCommandHandler commandHandler = new MyAggregateCommandHandler();
commandHandler.setRepository(fixture.getRepository());
commandHandler.setClaimedUserNameRepository(claimedUserNameRepository);
fixture.registerAnnotatedCommandHandler(commandHandler);
}

@Test

public void testExpireRichiestaIscrizione_happypath() throws Exception {
final MyAggregateId aggregateIdentifier = new MyAggregateId();
final String token = UUID.randomUUID().toString();
final String userName = “userName”;
final String plainPassword = “password”;
final String passwordHash = DigestUtils.sha1(plainPassword);

fixture//
.given(new MyAggregateCreatedEvent(aggregateIdentifier, userName, passwordHash, token))//
.when(new ExpireMyAggregateCommand(aggregateIdentifier, userName))//
.expectEvents(new MyAggregateExpiredEvent(aggregateIdentifier));
}

`

Note: Dubugging my Test I noticed the method

`

@EventHandler
public void handle(final MyAggregateNameExpiredEvent event) {
markDeleted();
}

`

was called twice and second time get the Exception, so error should be in the test irself or Command/Event roundtrip

Any suggestion are welcome

Could you send the entire stacktrace of the exception? I suspect something is wrong in the illegal state change detection, where the aggregate is loaded a second time.

Using markDeleted() in an Event Handler is the right place. The exception is intentional, since a deleted aggregate should not be retrieved anymore.

I know EventSourcedAggregate marked as deleted should never be loaded, bu I do not intentionally load It, here full stacktrace:

`

15:55:44.142 [main] DEBUG o.a.domain.IdentifierFactory - Looking for IdentifierFactory implementation using the context class loader
15:55:44.169 [main] DEBUG o.a.domain.IdentifierFactory - Looking for IdentifierFactory implementation using the IdentifierFactory class loader.
15:55:44.170 [main] DEBUG o.a.domain.IdentifierFactory - Using default UUID-based IdentifierFactory
15:55:44.615 [main] DEBUG o.a.commandhandling.SimpleCommandBus - Dispatching command [it.demanio.ap.domain.richiestaiscrizione.commands.ExpireRichiestaIscrizioneCommand]
15:55:44.621 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - Starting Unit Of Work.
15:55:44.622 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - Registering Unit Of Work as CurrentUnitOfWork
15:55:44.624 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Registering listener: org.axonframework.test.GivenWhenThenTestFixture$AggregateRegisteringInterceptor$1
15:55:44.637 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Registering listener: org.axonframework.eventsourcing.EventSourcingRepository$ConflictResolvingListener
15:55:44.640 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Registering listener: org.axonframework.repository.LockingRepository$LockCleaningListener
15:55:44.662 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - Committing Unit Of Work
15:55:44.662 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listeners of commit request
15:55:44.662 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listener [org.axonframework.test.GivenWhenThenTestFixture$AggregateRegisteringInterceptor$1] of upcoming commit
15:55:44.663 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listener [org.axonframework.eventsourcing.EventSourcingRepository$ConflictResolvingListener] of upcoming commit
15:55:44.663 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listener [org.axonframework.repository.LockingRepository$LockCleaningListener] of upcoming commit
15:55:44.663 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Listeners successfully notified
15:55:44.663 [main] DEBUG o.a.unitofwork.DefaultUnitOfWork - Persisting changes to aggregates
15:55:44.663 [main] DEBUG o.a.unitofwork.DefaultUnitOfWork - Persisting changes to [it.demanio.ap.domain.richiestaiscrizione.RichiestaIscrizione], identifier: [9b3b943d-8c62-45e0-a0f9-aa3122d02e40]
15:55:44.663 [main] DEBUG o.a.unitofwork.DefaultUnitOfWork - Aggregates successfully persisted
15:55:44.663 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - This Unit Of Work is not nested. Finalizing commit…
15:55:44.663 [main] DEBUG o.a.unitofwork.DefaultUnitOfWork - Publishing events to the event bus
15:55:44.664 [main] DEBUG o.a.unitofwork.DefaultUnitOfWork - Publishing event [it.demanio.ap.domain.richiestaiscrizione.events.RichiestaIscrizioneExpiredEvent] to event bus [org.axonframework.test.GivenWhenThenTestFixture$RecordingEventBus@5d4e9726]
15:55:44.664 [main] DEBUG o.a.unitofwork.DefaultUnitOfWork - All events successfully published.
15:55:44.664 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listeners after commit
15:55:44.664 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listener [org.axonframework.repository.LockingRepository$LockCleaningListener] after commit
15:55:44.664 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listener [org.axonframework.eventsourcing.EventSourcingRepository$ConflictResolvingListener] after commit
15:55:44.664 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listener [org.axonframework.test.GivenWhenThenTestFixture$AggregateRegisteringInterceptor$1] after commit
15:55:44.664 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - Stopping Unit Of Work
15:55:44.664 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listeners of cleanup
15:55:44.664 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listener [org.axonframework.repository.LockingRepository$LockCleaningListener] of cleanup
15:55:44.664 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listener [org.axonframework.eventsourcing.EventSourcingRepository$ConflictResolvingListener] of cleanup
15:55:44.664 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listener [org.axonframework.test.GivenWhenThenTestFixture$AggregateRegisteringInterceptor$1] of cleanup
15:55:44.664 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Listeners successfully notified
15:55:44.664 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - Clearing resources of this Unit Of Work.
15:55:44.665 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - Starting Unit Of Work.
15:55:44.665 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - Registering Unit Of Work as CurrentUnitOfWork
15:55:44.699 [main] DEBUG o.a.repository.LockingRepository - Exception occurred while trying to load an aggregate. Releasing lock.
org.axonframework.eventsourcing.AggregateDeletedException: Aggregate with identifier [9b3b943d-8c62-45e0-a0f9-aa3122d02e40] not found. It has been deleted.
at org.axonframework.eventsourcing.EventSourcingRepository.doLoad(EventSourcingRepository.java:179) ~[axon-core-2.3.2.jar:2.3.2]
at org.axonframework.eventsourcing.EventSourcingRepository.doLoad(EventSourcingRepository.java:56) ~[axon-core-2.3.2.jar:2.3.2]
at org.axonframework.repository.AbstractRepository.load(AbstractRepository.java:78) ~[axon-core-2.3.2.jar:2.3.2]
at org.axonframework.repository.LockingRepository.load(LockingRepository.java:102) [axon-core-2.3.2.jar:2.3.2]
at org.axonframework.repository.LockingRepository.load(LockingRepository.java:51) [axon-core-2.3.2.jar:2.3.2]
at org.axonframework.test.GivenWhenThenTestFixture$IdentifierValidatingRepository.load(GivenWhenThenTestFixture.java:535) [axon-test-2.3.2.jar:2.3.2]
at org.axonframework.test.GivenWhenThenTestFixture$IdentifierValidatingRepository.load(GivenWhenThenTestFixture.java:518) [axon-test-2.3.2.jar:2.3.2]
at org.axonframework.test.GivenWhenThenTestFixture.detectIllegalStateChanges(GivenWhenThenTestFixture.java:275) [axon-test-2.3.2.jar:2.3.2]
at org.axonframework.test.GivenWhenThenTestFixture.when(GivenWhenThenTestFixture.java:240) [axon-test-2.3.2.jar:2.3.2]
at org.axonframework.test.GivenWhenThenTestFixture.when(GivenWhenThenTestFixture.java:227) [axon-test-2.3.2.jar:2.3.2]
at it.demanio.ap.domain.richiestaiscrizione.commands.RichiestaIscrizioneCommandHandlerTest.testExpireRichiestaIscrizione_happypath(RichiestaIscrizioneCommandHandlerTest.java:116) [test-classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_65]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_65]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_65]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_65]
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) [junit-4.11.jar:na]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.11.jar:na]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) [junit-4.11.jar:na]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.11.jar:na]
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) [junit-4.11.jar:na]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) [junit-4.11.jar:na]
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.run(ParentRunner.java:309) [junit-4.11.jar:na]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) [.cp/:na]
15:55:44.700 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - Rollback requested for Unit Of Work for unknown reason.
15:55:44.700 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listeners of rollback
15:55:44.700 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Notifying listeners of cleanup
15:55:44.700 [main] DEBUG o.a.u.UnitOfWorkListenerCollection - Listeners successfully notified
15:55:44.700 [main] DEBUG o.a.unitofwork.NestableUnitOfWork - Stopping Unit Of Work

`

Ah, now I see. You are logging on debug level. This stacktrace does occur, because Axon is attempting to load the aggregate, to ensure it is also considered “deleted” when sourced from events. The exception is caught and not rethrown. The locking mechanism on the repository reports it’s releasing a lock because of the exception.

Nothing bad is happening.

Cheers,

Allard

Thanks a lot, I was going crazy.