I treat my persistent entity as an aggregate root, and I try to stick to this definition as much as possible and often find myself designing the entity that is quite fat.
I will give you an example.
In our system, our customers can have multiple investment “goals”, and the investment goals are supported by following the investment “plans”. And each investment plans have one portfolio, and the portfolio consist of multiple financial instruments.
When one of the plan’s instruments position got updated because the trade has settled, we have to renew the market value of
- customer’s overall combined market values and combined instrument positions
- market value of the goal that is supported by this plan
- plan’s market value.
- portfolio’s instrument position
For us, 1,2,3 and 4 must be renewed atomically at the same time, otherwise, we will confuse our clients and we cannot take that risk.
And this is a strong signal to me that Goal / Plan / Position objects all need to be in the same aggregate root.
It means that your entity’s state will be something like this:
case class GoalManagerState(manager:GoalManager)
And this state consists of nested objects:
case class GoalManager(goalId:UUID, goals:List[Goal]) case class Goal(plans:List[Plan]) case class Plan(instrumentPositions:List[InstrumentPosition]) case class InstrumentPosition(currentPosition:BigDecimal, settledOrders:List[Order]) case class Order(.......)
As you can see, this results in an entity that is very deep with many layers of nested objects inside of it. It will make the command handling and event handling very complex.
I’ve been dealing with such kind of complexities by using the traits, but still, I am wondering if this is a common thing with aggregate root. I am wondering how other Lagom users are dealing with this kind of complexities.