Aggreate Root holding reference to another Aggregate,how do i set up the dependencies ?

3,035 views
Skip to first unread message

sudarshan

unread,
Oct 24, 2011, 5:41:44 AM10/24/11
to DDD/CQRS
Hi,

I am starting of with trying to wrap my head around DDD/CQRS, for now
i am using a CQRS approach without event sourcing, so my Query side
DTO's basically get populated through Views, both Command and Query
side share the same Event Source in this case a RDBMS.

Further we use a ORM which acts as our data mapper/Repository.

I think i understand what aggregate roots are and there purpose in
life, and my question is a little implementation specific

Assume both Customer and Order are Aggregate Roots within the same
Bounded Context (For simplicity assume we have 1 BC only), The
Customer class has a reference to Set<Order> orders, So 1 customer can
have many orders,When i look up a customer I lazy load all his orders
as well, However because i want to ensure that all the dependecies of
Order AR are properly set , In the customerRepository itself I will
need to use something like OrderRepository.FindOrdersByCustomerId and
then do something like
customer.setOrders(orderRepository.FindOrdersByCustomerId(2)) ... Is
this a fair approach ?

One more approach I have is inject/put in the OrderRepository into the
Customer AR, and expose something like
findAllOrder() in the Customer AR

public void findAllOrder() {
OrderRepository.findAllOrderForCustomer(this.id)
}

Related to the above I also have another query

In order to establish a relationship between Order and Customer, IMHO
we have 2 options

Customer has Set<Order> orders and so a formal Foreign Key
relationship is made (Tight coupled)

OR

Customer has Set<OrderId> and we do not have a FK relationship but one
maintained in code (Loosely coupled)


Any guidelines on how to decide which to use when and is there a 3rd
approach ?


Michael Devenijn

unread,
Oct 24, 2011, 7:31:12 AM10/24/11
to ddd...@googlegroups.com
Sorry to say so but i think you should review your definitions about Aggregates and especially their boundaries.

Impliciating a Order Repo in the customer is really not what you want. at best (depending on your domain modelling) a reference to orders can be hold but really not more than that.
Again this is really not an implementation issue but clearing out your domain model (especially your aggregates and their boundaries)

M.

@yreynhout

unread,
Oct 24, 2011, 7:48:54 AM10/24/11
to DDD/CQRS
This question sounds like it has more to do with DDD than CARS.
- References to entities of another aggregate should be transient.
- If you must keep a persistable reference, use identifiers (composite
ones if we're not talking about the root).

Other observations
- Lazy loading is - me thinks - a problem long *solved* by ORMs,
combined with fetching strategies (http://www.infoq.com/presentations/
Making-Roles-Explicit-Udi-Dahan)
- Repository shields your code from how a customer aggregate is
(re-)constructed. Why involve yet another repository (the one for
fetching a customer's orders) internally for that purpose?
- Since you claim Order is an aggregate, why are you trying to pretend
it's part of the state of Customer aggregate? Why not have your
customer and order object collaborate instead of jumping through hoops
trying to make one state of another?
- All this seems very structural, not behavioral.

More important questions you should answer first: What use case
involves a customer and all its orders? => Does my code reflect the
model I discussed with my domain expert? => Have I analysed this
problem well enough?

Hope this makes you rethink.

P.S. No offense intended (seems obligatory these days).

sudarshan

unread,
Oct 24, 2011, 8:25:48 AM10/24/11
to DDD/CQRS
Thanks for the replies no offence taken :)

The CustomerRepository can hold a reference of OrderRepository
approach was taken from

http://stackoverflow.com/questions/6118174/how-should-i-enforce-relationships-and-constraints-between-aggregate-roots/6118376#6118376


My example is not from a proper project, I am rather curious about how
best to handle a situation where a AR will need to hold the reference
of another AR.

Can you please explain what you mean by "customer and order object
collaborate" ?

Mainly want to know in cases like these where the Customer AR is
"related" to the Order AR how best should it be modeled ?

-- If you must keep a persistable reference, use identifiers ---------
Is this the only recommended way ?

I am aware this may not be the best example on which this question
should be asked, however we could change the example and use any 2
AR's, if they are closely related in the model, how is it suppose to
be modeled.



Thanks

satish venkatakrishnan

unread,
Oct 24, 2011, 5:03:34 PM10/24/11
to ddd...@googlegroups.com

@yreynhout

unread,
Oct 24, 2011, 5:15:14 PM10/24/11
to DDD/CQRS
There's many ways an aggregate can "reference" another aggregate.

One variation is that aggregate A gets a message about aggregate B and
by virtue of that message starts tracking information in aggregate A
about aggregate B. Why? Because some future behavior of A requires
that information about B. It's not a pointer, rather a copy of its
data (at least some of it).
Another is aggregate A requiring aggregate B to complete an operation
(aka a collaboration between them): A a; B b; a.SomeOperation(b)
{ b.GuardSomeOperation(); ... }
Mind you that none of these make any promises about B's consistency
(otherwise B would not be its own aggregate ;-). Only A's consistency
is/should be guaranteed.

As for sticking with identifiers only (instead of pointers), I can
point you here: http://domaindrivendesign.org/events/ddd-summit-2011

On Oct 24, 2:25 pm, sudarshan <sudarsha...@gmail.com> wrote:
> Thanks for the replies no offence taken :)
>
> The CustomerRepository can hold a reference of OrderRepository
> approach was taken from
>
> http://stackoverflow.com/questions/6118174/how-should-i-enforce-relat...

sudarshan

unread,
Oct 25, 2011, 3:28:39 AM10/25/11
to DDD/CQRS
Thanks for the replies :)

Looks like i am failing to understand something very basic, or else i
am just stuck up in thinking the primary key, foreign key way ....

I have 1 query for the two options given above

One variation is that aggregate A gets a message about aggregate B
(About which instance of AR B .... how do you locate that instance
without a relationship in the DB)

Another is aggregate A requiring aggregate B to complete an operation
(aka a collaboration between them): A a; B b; a.SomeOperation(b)
(About which instance of AR B .... how do you locate that instance
without a relationship in the DB)


which instance of AR B gets passed to AR A ? ... I mean somewhere in
the DB schema a PK,FK needs to be formed .... in a ORM world in order
to achieve this we need a reference .... now if we kick out this
option the only other option i see is to maintain identifiers ....

One other pseudo solution which seems to be coming out regularly is
that such interaction may not be needed it self ... and one of the
AR's become a entity or the interaction itself is modeled away via
eventual consistency and so on .....


In this post http://www.udidahan.com/2009/01/24/ddd-many-to-many-object-relational-mapping/

The author mentions some thing like this

"Going back to the code above we see that the right choice is
jobBoard.Post(job);"

I am assuming here that JobBoard has a collection of Jobs in it ...

Also in that post i did not get if finally Job was mean to be a AR, or
whether it finally just became a Entity .... and either way my doubts
still persist ...

Like most things in life different people tend to believe in different
solutions because the stackoverflow posts definitely point towards
compositions of repositories ... so it does get a little confusing for
a newbie who's just feeling his way through ...


It seems like a lot of people are having the questions I have and so
Part 2 of Design aggregates seems to be dedicated to it :)

"Part I has focused on the design of a number of small
aggregates and their internals. There will be cases that
require references and consistency between aggregates,
especially when we keep aggregates small. Part II of this
essay covers how aggregates reference other aggregates as
well as eventual consistency."

I would not mind getting a heads up on things here though :)


Thanks

satish venkatakrishnan

unread,
Oct 25, 2011, 9:44:33 AM10/25/11
to ddd...@googlegroups.com
May be we need find a good example so that we can design one interaction and how it should be modeled ...

@yreynhout

unread,
Oct 25, 2011, 11:29:30 AM10/25/11
to DDD/CQRS
- The message contains data about B, so what instance of aggregate B?
The message contains all I need to know to carry out the operation. So
yes, quite often I'm content with the identifier of another aggregate
or entity within. I fail to see the need to tie my relational model
back to aggregate B. In the long run that will only cause friction.
- In the collaboration case, you typically have the application
service (or command handler) ask the repository of B's type to find B
and pass it on to A's SomeOperation.
There's no magic here. Just a different way of going about it.

On 25 okt, 09:28, sudarshan <sudarsha...@gmail.com> wrote:
> Thanks for the replies :)
>
> Looks like i am failing to understand something very basic, or else i
> am just stuck up in thinking the primary key, foreign key way ....
>
> I have 1 query for the two options given above
>
> One variation is that aggregate A gets a message about aggregate B
> (About which instance of AR B .... how do you locate that instance
> without a relationship in the DB)
>
>  Another is aggregate A requiring aggregate B to complete an operation
>  (aka a collaboration between them): A a; B b; a.SomeOperation(b)
> (About which instance of AR B .... how do you locate that instance
> without a relationship in the DB)
>
> which instance of AR B gets passed to AR A ? ... I mean somewhere in
> the DB schema a PK,FK needs to be formed .... in a ORM world in order
> to achieve this we need a reference .... now if we kick out this
> option the only other option i see is to maintain identifiers ....
>
> One other pseudo solution which seems to be coming out regularly is
> that such interaction may not be needed it self ... and one of the
> AR's become a entity or the interaction itself is modeled away via
> eventual consistency and so on .....
>
> In this posthttp://www.udidahan.com/2009/01/24/ddd-many-to-many-object-relational...

sudarshan

unread,
Oct 25, 2011, 1:16:42 PM10/25/11
to DDD/CQRS
Well, What i meant was .... using my order and customer example .....

If i want say provide a discount on all orders for customer x

i would need to to something like

Customer c = loadCustomer(x)

Set<Order> orders = c.getOrders()

Or say

Set<Order> orders = OrderRepo.getAllOrdersForCustomer(c)

I am trying to say that AR A and AR B are related ... where an
instance of AR A is related to certain other instances of AR B ... and
that needs to be modeled ...

Are you suggesting the optimum way to do it is using identifiers ??

Joseph Daigle

unread,
Oct 25, 2011, 3:26:29 PM10/25/11
to ddd...@googlegroups.com
Presumably you have some service or application handler for the business case of providing a discount; it can have a reference to your OrderRepository. I think you're better off using your latter example:

Set<Order> orders =  OrderRepo.getAllOrdersForCustomer(c);

Or better yet just pass the customer_id into your repository method, no need to worry about the Customer AR at all.

sudarshan

unread,
Oct 26, 2011, 6:47:57 AM10/26/11
to DDD/CQRS
Yes thank you .... however for that to work at the schema level ... we
either need a FK ... or we just need to store the customer_id as a
column in the order table ...


My primary question was ... which approach to take when ... are there
any guidelines for the same ??

Thanks

satish venkatakrishnan

unread,
Oct 26, 2011, 7:06:49 AM10/26/11
to ddd...@googlegroups.com
i will take your second one ie storing the customer id in the order table without the FK (MY opinion) since for me order is aggregate root  and it needs just the reference of the customer through id

Philip Jander

unread,
Oct 26, 2011, 7:11:33 AM10/26/11
to ddd...@googlegroups.com
Am 26.10.2011 12:47, schrieb sudarshan:
> Yes thank you .... however for that to work at the schema level ... we
> either need a FK ... or we just need to store the customer_id as a
> column in the order table ...
>
>
> My primary question was ... which approach to take when ... are there
> any guidelines for the same ??
>

A common definition of an aggregate is by a consistency boundary. In
memory, that implies that there must be no direct references (i.e.
pointers) between two aggregates.
If you use a RDBMS 3nf storage for your domain model state, it follows
that you can only use ID storage to reference other aggregates'
entities, not FKs.
Once your system grows beyond a single server, that other aggregate is
possibly not even persisted on the same DB server.

Further down that road:
Once you get rid of DB table relationships, the question arises why to
use a 3nf model in the first place.
So you start using 1NF/key-value stores. Then you ask yourself why to
use a RDBMS is the first place.
Then you start using document DBs :)

Cheers
Phil

satish venkatakrishnan

unread,
Oct 26, 2011, 7:40:05 AM10/26/11
to ddd...@googlegroups.com
adding the phil's points there is a possibility for having a wrong customer id can come in mind because by removing the FK that means we need a way to verify the customer id sent should be a valid. which the validation component should take care

Michael Brown

unread,
Oct 26, 2011, 10:07:45 AM10/26/11
to ddd...@googlegroups.com
What is an order without a Customer? Orders belong under the Customer AR. When I make an order it's Customer.CreateOrder(), if I want all Orders for a Customer, I request Customer.GetOrders().

Well what about reports? What if I want to get an aggregate of sales across customers? Well, that's what the read model is for. But the Command Model should only deal with orders through the Customer.

Joseph Daigle

unread,
Oct 26, 2011, 10:32:29 AM10/26/11
to ddd...@googlegroups.com
You're right in that an Order is nothing without a Customer. But what about a Customer is important for an Order other than the customer_id? You can enforce this domain constraint simply by making the Order's ctor require a customer_id.

Philip Jander

unread,
Oct 26, 2011, 10:56:51 AM10/26/11
to ddd...@googlegroups.com

> What is an order without a Customer? Orders belong under the Customer AR. When I make an order it's Customer.CreateOrder(), if I want all Orders for a Customer, I request Customer.GetOrders().
That would make Order a part of the Customer aggregate. I agree, that
this is a very likely model. However, the original poster explicitly
stated to have separate aggregates. Yves already noted that the whole
setup might benefit from rethinking ;)

Cheers
Phil

Michael Brown

unread,
Oct 26, 2011, 11:07:03 AM10/26/11
to ddd...@googlegroups.com
Gotcha...I guess I was doing the rethinking for him. Order is not an aggregate root. It's an important entity from a reporting perspective but it doesn't exist without a customer. I guess we can consider that a "domain smell" having a strong dependency between two ARs.

-----Original Message-----
From: ddd...@googlegroups.com [mailto:ddd...@googlegroups.com] On Behalf Of Philip Jander
Sent: Wednesday, October 26, 2011 10:57 AM
To: ddd...@googlegroups.com
Subject: Re: [DDD/CQRS] Re: Aggreate Root holding reference to another Aggregate,how do i set up the dependencies ?

sudarshan

unread,
Oct 27, 2011, 12:06:45 AM10/27/11
to DDD/CQRS
Well ... i agree with the fact my example was not the best :) .... but
my intention was to ask how do you model a situation when there is a
need to hold a reference for a AR in another AR ....

Maybe say AR doctor and AR patient .... 1 doctor treats many patients
and 1 patient is treated by many doctors ....

The consistency boundaries of both AR's are mutually exclusive ... and
still for certain operations (not reporting) we are going to want to
get all Patients that a particular doctor treats .....

Or all doctors treated by a particular patient ...

My understanding right now after the discussions is that in such
cases ....
its better to have a valueobject representing the unique identifier of
say AR doctor within AR patient

Rather than having a reference of AR Doctor .....

Again it could be debated that each of these should not be a AR and so
on ... or that such a relationship is not needed at all ....

But my question is more about the technical design ... and which is
the most "recommended way"... and why ??

@yreynhout

unread,
Oct 27, 2011, 3:55:21 AM10/27/11
to DDD/CQRS
Yes, at least for me.

@yreynhout

unread,
Oct 27, 2011, 7:35:54 AM10/27/11
to DDD/CQRS
The recommended way == it depends

@yreynhout

unread,
Oct 27, 2011, 7:51:34 AM10/27/11
to DDD/CQRS
The general problem I have when people start their sentences with "I
have AR X and AR Y ..." is that they've already decided what those
aggregates should be, without providing any context as to how they
came about them (i.e. how you found them). Instead of starting out
from a "structural" point of view, why not start from a behavioral one
(e.g. a specific use case)? IMHO, you'll get a broader range of
answers. Granted, some of them will not be feasible. Others might not
meet yet to be disclosed constraints/invariants (which is a good
thing, i.e. the path towards the true invariants). There's little
point in putting the technical stuff first, but you're free to
disagree.

On 27 okt, 06:06, sudarshan <sudarsha...@gmail.com> wrote:

Philip Jander

unread,
Oct 27, 2011, 9:47:02 AM10/27/11
to ddd...@googlegroups.com
@sudarshan:
if you haven't seen it yet, take a look at Udi Dahan's conference talk
from DDDX2011 on composie applications with skillsmatter.com. There is a
brief section on building up aggregates. It may be quite eye-opening to
see a structural "customer" torn to pieces (almost literally).

Phil

Michael Brown

unread,
Oct 27, 2011, 1:21:27 PM10/27/11
to ddd...@googlegroups.com
It depends on the Domain. For a Clinical Management System, the patient is a "Customer" and the Doctor has Customers or the Clinic has Customers and Doctors Treat Patients. So a Person plays multiple roles in the system. You have John Doe (entity) who is a Customer (role) for the Clinic (entity). John Doe Visits (transaction) the Clinic as a Customer and Jack Sprat (entity) is a Doctor (role) who Treats (transaction) John Doe as a Patient (role). Jack Sprat is an Employee (role) of the Clinic which is an Employer (role) that Employs (transaction) Jack Sprat. After Jack Spratt Treats John Doe, the Clinic Bills (transaction) John Doe either directly or through his Insurance Provider (role), Major Medical (entity) as a Financially Responsible Party(role).

This is what Peter Coad's book Java Modeling in Color in UML boils down to. Break your system down into entities (party, place, or thing), transactions, and the roles entities play within those transactions. Now that you've identified those objects, you can apply the concepts of DDD to further refine your model.

For every transaction there is an initiator, an entity who starts the transaction. They act as the Aggregate Root for the transaction. So John Doe is the Aggregate Root for a Visit. Jack Sprat is the Aggregate Root for Treating the Patient. The Clinic is the Aggregate Root for Employing Jack Sprat, and Billing the Patient.

The Doctor and Patient aren't aggregate roots...they are roles in the Treatment aggregate. Jack Sprat as the initiator of the Treatment serves as the Aggregate Root (you could argue that his Role as Doctor is the root, but you get to a Party's role through the Party). In short, the Role (Doctor, Patient) is not the Aggregate Root. The Party that plays the Role should be the AR. And the Aggregate boundary forms around the Transaction.

A bit of further analysis might uncover that we don't care about the Patient and his Visit...but rather about the Clinic Admitting a Patient. So now rather than looking at a specific patient and looking at his visits, we can look at the clinic as a whole and look at all Admissions. And if we need to we can filter it down to a specific patient and the times he was Admitted to the Clinic.

There is another object type that we aren't discussing here, and those are what Coad calls Descriptions and Evans calls Value Objects. An example would be during John Doe's Treatment, Jack Sprat Prescribes (another event) a dosage of Aspirin. Aspirin is a Value Object, it describes the Drug the patient is supposed to take with the Prescription. When John Doe takes the Prescription to the Pharmacist, it doesn't matter specifically which pills are given to John, just that they are Aspirin.

Note how there is a flow to this story, one transaction is usually followed by another. A Visit is followed by a Treatment followed by a Billing and eventually a Payment. Looks a lot like a Value Stream right? That's what you should hone in on when modeling a system, how does your application result in value being provided to the stakeholder. If you get that right, you'll have happy stakeholders.

This model would be totally different if we were creating a Personal HealthCare Management System (like Microsoft HealthVault) where the "stakeholder" is an individual tracking his health and doctor visits, medication, exercise, fitness, etc.

Udi Dahan gives a talk about making roles explicit and how it impacts domain discovery and simplifying a model. Although he doesn't mention Color Modeling specifically, it's the same idea. I can attest to how I've become a better modeler by following this approach. Hopefully this helps you on your path as well.

@yreynhout

unread,
Oct 27, 2011, 4:12:31 PM10/27/11
to DDD/CQRS
This is SOM (part of the PC series of course). I heard of this
coloring business afterwards (donnow which was first - the book you
mention is a predecessor). Very good way of modeling indeed. More
people should read it.

Nuno Lopes

unread,
Oct 27, 2011, 4:33:40 PM10/27/11
to ddd...@googlegroups.com
Coad Descriptions are note the same as Eric's value objects.


Sent from my iPhone

Michael Brown

unread,
Oct 27, 2011, 6:03:47 PM10/27/11
to ddd...@googlegroups.com
You're right, they aren't exactly the same. But if you add the convention that descriptions are immutable, they are one and the same. Their only purpose is to provide information about other objects in the system. They don't have an identity but are rather categorical descriptions. To me descriptions and value objects are the same.

Sent from my Windows Phone

From: Nuno Lopes
Sent: 10/27/2011 4:34 PM

Nuno Lopes

unread,
Oct 28, 2011, 3:55:43 AM10/28/11
to ddd...@googlegroups.com
No, Coad equates it to a catalogue description.

The pattern is Description - Thing. 

In SOM is the same has Item - Specific Item. 

A value object for all intents it's  a value. Values are qualified in context.For instance Age is a value. When in the context of a Person is qualified as the person's Age. Person-Age is the qualifier. 

I'm just trying to say that Items are really powerfull and often are mistaken as Specific Items. They can work for instance as Templates for other objects.  

Sent from my iPhone

Nuno Lopes

unread,
Oct 28, 2011, 4:03:07 AM10/28/11
to ddd...@googlegroups.com
An example is for instance 

Exam - SpecificExam - Examination 

Exam describes the a specific exam done during an examination.

Say for instance a national maths exam. 

Sent from my iPhone

On Oct 27, 2011, at 11:03 PM, Michael Brown <mbr...@kharasoft.com> wrote:

sudarshan

unread,
Nov 1, 2011, 4:36:47 AM11/1/11
to DDD/CQRS
Hi

I have been looking at how to go about this AR references a AR
scenario ....

and i stumbled upon this

http://rogeralsing.com/2009/11/08/two-flavors-of-ddd/


and it heads the nail bang on the head !!!



Thanks

On Oct 28, 1:03 pm, Nuno Lopes <nbplo...@gmail.com> wrote:
> An example is for instance
>
> Exam - SpecificExam - Examination
>
> Exam describes the a specific exam done during an examination.
>
> Say for instance a national maths exam.
>
> Sent from my iPhone
>
> On Oct 27, 2011, at 11:03 PM, Michael Brown <mbr...@kharasoft.com> wrote:
>
>
>
>
>
>
>
> > You're right, they aren't exactly the same. But if you add the convention that descriptions are immutable, they are one and the same. Their only purpose is to provide information about other objects in the system. They don't have an identity but are rather categorical descriptions. To me descriptions and value objects are the same.
>
> > Sent from my Windows Phone
> > From: Nuno Lopes
> > Sent: 10/27/2011 4:34 PM
> > To: ddd...@googlegroups.com
> > Subject: Re: [DDD/CQRS] Re: Aggreate Root holding reference to another Aggregate,how do i set up the dependencies ?
>
> > Coad Descriptions are note the same as Eric's value objects.
>
> > Sent from my iPhone
>

@yreynhout

unread,
Nov 1, 2011, 5:33:15 AM11/1/11
to DDD/CQRS
While a good read, it's still focusing too much on the structural
aspect. Why would I want to lazy-load related aggregates? What command
would that be? Again, I get the feeling that solving this fictional
problem is getting ahead of oneself. Aggregates solve immediate
consistency problems, while things like sagas solve eventual
consistency ones. Lazy-loading in any shape or form is just a poor
attempt at bluring the lines. If your using your write model for
reading as well, this is what you'll be fighting. To me it's the
reason for CQRS existence.

sudarshan

unread,
Nov 1, 2011, 9:37:38 AM11/1/11
to DDD/CQRS
Yes I agree with you ... I was pointing out at the fact that even he
speaks about "Aggregate Documents" and this seems to be preferred
approach :)
Reply all
Reply to author
Forward
0 new messages