Aggregate loading from a repository resulting in an IllegalStateException

Hi Allard,
In one of our requirement, we need to check if the aggregate exists and current state of aggregate before executing other commands on that. There are some times due to concurrency of requests initial command which is responsible for creation of aggregate and subsequent command which need to work on this aggregate work in parallel. But while loading the aggregate from the repository we get this exception

java.lang.IllegalStateException: No UnitOfWork is currently started for this thread.

Please suggest.

Thanks,
Vijaya

Hi,

“check if the aggregate exists and current state of aggregate” sounds like a query. That’s what a query model is for. Doing that directly on aggregates is dangerous, as it leads to unnecessary coupling (your aggregate internals/state is exposed to another component).

However, to load an aggregate, you need to start a Unit of Work:
UnitOfWork uow = DefaultUnitOfWork.startAndGet();
// do what you need
uow.rollback(); // or commit();

Cheers,

Allard

Thanks Allard!

I understand the point to load an aggregate and checking the state is not the right choice. Is there any other best way you suggest to cater to this requirement. Here are the requirement detail I want to share

On Request arrival command is invoked which is responsible for the creation of aggregate. Now processing the response for that request we assume aggregate is in place, but in case it is not we need to create. Hence we need to check if aggregate exists or not? Earlier we were deciding as part of some our DB entries populates as part of event handlers execution as part of first command execution. But it was noticed in request and response arrived at the same time, DB record yet to be populated as part of event handling. Now if record does not exist we do issue same command which is responsible for Aggregate creation and this results in Concurrency Modification exception.

Finding out whether an aggregate exists is a query. So basically, you just need to have a query model (projection) in place that’s able to answer that question. If one doesn’t exist, create it, otherwise update the existing one. In the end, you need to know the ID of an aggregate if you want to update it.
Alternatively, if you use an externally provided ID, you can also assume an aggregate simply exists and create it when the update fails because of a “AggregateNotFoundException”.

The first solution is more CQRSy, though.

Cheers,

Allard