Acessing aggregates directly

Hi Allard, you said elsewhere (although in a slightly different context than mine):

(…) a Saga should send commands instead of accessing an Aggregate directly.
(…)

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:

I extended the Aggregate root like this (I called it ClosableAggregateRoot):

`
private boolean closed = false;
public void close() {
closed = true;
}
public boolean isClosed() {
return closed;
}

`

so at some point I want obviously to check if the aggregate “is closed” (the use case I mention before of waiting until certain condition is true to return a result to the client).

So I have a utility method that does that:

public void waitUntilClosed(Object id) throws InterruptedException { Lock lock = new ReentrantLock(); Condition closed = lock.newCondition(); ClosableAggregateRoot aggregate = (ClosableAggregateRoot) getAggregate(id); while (!aggregate.isClosed()) { try { lock.lock(); closed.await(WAIT_TIME, TimeUnit.SECONDS); } finally { lock.unlock(); } aggregate = (ClosableAggregateRoot) getAggregate(id); } }

So the question is, what is the best way to implement the getAggregate(id)?

Until now I tried 2 ways:

  • end a command to the aggregate that simply returns itself
  • getting it directly from the store

The 1st is clumsy because I will have to have a specific command to do that that users of the code would have to be aware.
The 2nd one you say " only be used if there are no other options left".

Do you think I have more options left in this case?

Cheers.

Hi,

the rules are simple: if you want to know something, use a query model. When you want to do something, send a command. If you want to wait for something to happen: listen to events.
That why you should never ask the aggregate anything. In my own projects, the aggregates are in a separate module (jar), and no other module is allowed to have a dependency on it.

So if you want to know if an aggregate is closed, listen for the AggregateClosedEvent. Or, maintain a query model where you can ask for it.

Cheers,

Allard