Sagas cannot load aggregates from repositories

One thing we noticed when implementing some saga classes is that when
you try and load an aggregate from within the saga using the
Repository.load method you get the exception below:

java.lang.IllegalStateException: No UnitOfWork is currently started
for this thread.
  at
org.axonframework.unitofwork.CurrentUnitOfWork.get(CurrentUnitOfWork.java:
58)
  at
org.axonframework.eventsourcing.EventSourcingRepository.doLoad(EventSourcingRepository.java:
119)
  at
org.axonframework.eventsourcing.EventSourcingRepository.doLoad(EventSourcingRepository.java:
54)
  at
org.axonframework.repository.AbstractRepository.load(AbstractRepository.java:
70)
  at
org.axonframework.repository.LockingRepository.load(LockingRepository.java:
119)

To get around this we simply store the value from aggregate we want by
handling the appropriate event however this seem cumbersome.

The UOW is registered as part for the command handling but should it
also be registered when a saga handler is invoke or is there an
underlying architectural or design reason whyt sagas cannot load
aggregates from the repository?

I think you only can load aggregate from command handler…you can fire commands from the saga though via commanbus…so saga can be event handler to comand generation mapper/translator for inter AR communication and store state during that coordination cycle…Allard has clarified this nicely in this thread below.

https://groups.google.com/d/topic/axonframework/d9Qrp8EyQZI/discussion

That’s totally correct: a Saga should send commands instead of accessing an Aggregate directly.

The architectural background for this is: decoupling. There can (read: should) be no guarantee that the aggregate “lives” in the same machine as the Saga in distributed environments. If the Saga sends out a command, it’s a lot easier to route that command to the machine that holds the aggregate. Although these scalability features are not necessary for the majority of applications, it good practice to stick to these design principles. If scalability does peek around the corner, you’ll be ready for it.

If, against all advice, you feel you must load the aggregate inside the Saga, you can use DefaultUnitOfWork.startAndGet() to get a reference to a unit of work. Don’t forget to either uow.commit() or uow.rollback(). This option should only be used if there are no other options left. Generally, there are plenty of other options left :wink:

Cheers,

Allard