One-to-many relationship between the aggregate roots

1,289 views
Skip to first unread message

Joo Lee

unread,
Jan 3, 2017, 12:25:56 PM1/3/17
to DDD/CQRS
Hello all,

Newbie questions so please bear with me (2 weeks into CQRS/DDD!)

I have a PortfolioEntity which is the aggregate root. And I have a PositionEntity which is also the aggregate root. 
PortfolioEntity has a state of Optional <PortfolioEntity> and PositionEntity has Optional<Position> as a state. (i.e. Portfolio and Position are the classes that carries the states for each entities)

And  just like one person can buy multiple stocks using one personal account, one Portfolio object can have one or more Position objects in it.

And I have two questions

1) I understand that in DDD it is better not to have the direct reference to other aggregate root, instead, it is recommended to have Unique Identifier of the another aggregate root if you have to reference it inside your Entity.

Then does it mean that Position class should have List[GUID] instead of List[Position]? Or perhaps, I should not just remove List[Position] or List[GUID] from the Portfolio class at all,instead, let Position class to have a reference to PortfolioEntity. (i.e. one-way reference from Position to Portfolio instead of bi-directional references between the two aggregates)
Which one do you think makes more sense in CQRS?

2) Do you think the PositionEntity really is an aggregate root? I believe the answer is yes because each Position has its own lifecycles such as New, Open and Closed. And our company wants to keep the audit trails of Position changes for various business reasons. 

Thanks,


Joo

Ben Kloosterman

unread,
Jan 3, 2017, 7:30:25 PM1/3/17
to ddd...@googlegroups.com
BK> Search the history ...

On Wed, Jan 4, 2017 at 3:25 AM, Joo Lee <joo.an...@gmail.com> wrote:
Hello all,

Newbie questions so please bear with me (2 weeks into CQRS/DDD!)

I have a PortfolioEntity which is the aggregate root. And I have a PositionEntity which is also the aggregate root. 
PortfolioEntity has a state of Optional <PortfolioEntity> and PositionEntity has Optional<Position> as a state. (i.e. Portfolio and Position are the classes that carries the states for each entities)

BK>Start the design with the aggregate / BL  not the entities.  

And  just like one person can buy multiple stocks using one personal account, one Portfolio object can have one or more Position objects in it.

And I have two questions

1) I understand that in DDD it is better not to have the direct reference to other aggregate root, instead, it is recommended to have Unique Identifier of the another aggregate root if you have to reference it inside your Entity.

BK> Links are nearly always ( and for a new comer always) via a reference like a guid  .

Then does it mean that Position class should have List[GUID] instead of List[Position]? Or perhaps, I should not just remove List[Position] or List[GUID] from the Portfolio class at all,instead, let Position class to have a reference to PortfolioEntity. (i.e. one-way reference from Position to Portfolio instead of bi-directional references between the two aggregates)
Which one do you think makes more sense in CQRS?

2) Do you think the PositionEntity really is an aggregate root? I believe the answer is yes because each Position has its own lifecycles such as New, Open and Closed. And our company wants to keep the audit trails of Position changes for various business reasons. 

BK> Hard to say  , probably - life cycle is irrelevant  .  Optional<Position>  under the entity does not make sense if i read it correctly maybe the aggregate root holds a Optional<PositionEnity> . In CQRS Aggregate roots normally have their own fields eg the position enitiy fields belong to the AR not a separate entity. Remember an AR can be a  tree of objects/ entities not just one - it is a consistency boundary .



Ben

Jakub Pilimon

unread,
Jan 4, 2017, 2:49:16 AM1/4/17
to DDD/CQRS


Hard to say given this description

You have to analyze if Portfolio and Positions should be always strongly consistent after every possible use-case. If not maybe List of value objects referencing Positions would be enough. 
Consider introducing something more meaningful that List[Position] under Portfolio, maybe some concept missed from your ubiquitous language that would encapsulate that list. Maybe "Positions" or something like that. 

Also, the fact that your Position has a lifecycle does make it an aggregate, it probably makes it an entity. If tyou need to keep tracks of changes, consider storing events.

Renato Cavalcanti

unread,
Jan 4, 2017, 7:05:06 PM1/4/17
to DDD/CQRS
I will echo the suggestions bellow, try not to think on lifecycle but consistency boundary. 

Also, make sure you understand the difference between an Aggregate and an Entity. It's not because an object is identifiable (hence an Entity) and has a lifecycle that it must be an Aggregate.

An Aggregate can be made of one or more objects in which the most prominent one gives the name to the Aggregate (it's also called the aggregate root). The root is an Entity because it does have an unique identifier, but it can contain other Entities and Value Objects.

About the audit log, nothing holds you to have audit on entities living inside an Aggregate. Since you are choosing for CQRS, you can (and probably will) have events expressing mutations on those inner objects.

Always think on transaction terms:
Aggregate == Consistency Boundary

As a consequence, you can't have one inside another. 
If you nest them, changing the inner one, means changing the outer one. That means that your consistency boundary is always the outer one and therefore there is only one Aggregate. 

I hope this give you enough insight on what is an Aggregate.

Cheers,
Reply all
Reply to author
Forward
0 new messages