How to decide the structure of the Aggregate class by the relationship of entities ?

How to decide the structure of the Aggregate class by the relationship of entities ?


I feel confused when comparing Axon-trade’s model and the definitions of the aggregate classes.

Here is the model diagram:


Here are parts the aggregate classes:

public class OrderBook {
    private OrderBookId orderBookId;
    private SortedSet<Order> buyOrders;

private SortedSet sellOrders;

// methods and constructor are omitted

public class Order {

    private OrderId orderId;
    private TransactionId transactionId;
    private final long itemPrice;
    private final long tradeCount;
    private final PortfolioId portfolioId;
    private long itemsRemaining;
   // methods and constructor are omitted


You can see that:

  1. The diagram shows that OrderBook has relationship with Company, while the aggregate class OrderBook doesn’t hold the companyId
  2. The diagram shows that Order does NOT has direct relationship with Portfolio, while the aggregate class Order holds the portfolioId

Although the view/projection table fully reflect the model diagram above as well as the denormalized fields, I wonder why the aggregate class does not reflect the model at least.

I also notice that the check in the axon-trade project depends on the data in view/projection, would it be safe ? If a user sells the same stock twice quickly, the 2nd selling may be executed before the portfolio view of 1st selling get updated , then an oversold would happen. In this case, would it better make the check on Aggregate ?


Is my question too easy or too hard to get replied ?

在 2020年1月21日星期二 UTC+8下午4:09:27,sean.c写道:

Hi Sean,

the reason those fields don’t appear in the command model aggregate is because they don’t play any role in deciding what the outcome of a command is.
The CompanyID in an OrderBook, for example, simply wouldn’t change anything. Think about it this way: does an OrderBook what it’s registering (and executing) trades for? Not really, it just needs to keep track of which orders have been placed and when they’re considered ‘executed’.

I would argue this the most powerful aspect of CQRS: the ability to create models based on what’s really necessary, rather than some representation of ‘reality’ on top of which we try to implement logic.

Hope that makes sense.


Hi Allard,

Thank you very much for your reply. In the past few years, I have being used to considering models from the both of behavior and representation , and create POJO to fully reflect the model. While using CQRS, it should be a different way to consider which parts belong to aggregate and which belong to projection. Thank you again. you make me realize the power of CQRS deeper.


在 2020年1月26日星期日 UTC+8上午2:04:07,Allard Buijze写道: