Reputation: 93
In my domain model I've got two principal entities: User and Event, both which I've decided to make aggregate roots. Users and Events have a one-to-many relationship wherein Users can create several events. However, an Event does not necessarily have a corresponding User (i.e. created by the admin) and has its own set of properties / entities. An Event should be able to be manipulated independently of a User.
Given these relationships, I'm wondering if I've done something wrong in my modelling? Is it alright to have the User aggregate root reference another aggregate root? Given that an Event can be manipulated independently of a User, would that introduce any risks to the User's consistency?
Upvotes: 1
Views: 956
Reputation: 3929
It is totally fine to have one aggregate referencing another aggregate if this reflects the domain model of your business. Also, you already pointed the need for having separate manipulations (transactions) for event aggregates independent of a user.
The thing when actually realizing the model in your code you should make sure of is to not reference a full event aggregate object in user but rather a reference.
For such cases a custom value object, such as EventId which strongly types the reference to the event aggregate would make sense. The EventId class might only contain the id of the Event aggregate but makes the reference type explicit throughout your code.
Depending on your needs their could also be other data of interest of the Event that is needed for the business logic of User. In this case you could also consider creating a custom value object that contains that information, e.g. UserEvent which contains the EventId alongside other information you need. You will know the best appropriate name of course...This also makes very explicit what data of the Events the User aggregate is really dependent of to keeps it's business logic invariants in tact.
In his book Implementing Domain-Driven Design Vaughn Vernon illustrates an example of a similar constellation where he models the agile project management domain with Product and BacklogItem being separate aggregates but Product referencing several related backlog items as a collection of ProductBacklogItem objects. See https://github.com/VaughnVernon/IDDD_Samples/blob/master/iddd_agilepm/src/main/java/com/saasovation/agilepm/domain/model/product/Product.java
Note: In this case he chooses Productbacklogitem to be an entity which is required to make persistency of the collection easier for Hibernate which is used in this case but having another persistency mechanism in place which allows to easily store object collections in the same table or even having a key value store would change this decision to use value objects instead of course.
Upvotes: 2