There is a school of thought, prevalent today, that says: A Domain model should always be independent of (and thus never call) the Persistence- (aka Repository) or Service- layers. I dont yet know of an established name for the architecture implied by the rule, so I shall refer to it as a Independent Domain and the reverse, architectures where the domain model references Repositories (or the like) a Co-dependent Domain.
I dont subscribe to the view that Co-dependent Domains are bad or prohibited. While Independent Domains work well in many situations, there are times where its practical, or just plain tractable, to back a domain-object method with a query to a repository. Other times, we would like a domain object to emit an domain event to a subscriber in the service layer, who might convert it into an email. In fact, rigid adherence to an Independent Domain rule can cause harm by encouraging domains to become Anemic.
Assumed Context
- Rich Domains with classic object-oriented encapsulation are desirable. In such a system, the service layer is thin and virtually all code lives on the domain objects.
- An architecture loosely like diagram (dotted arrows denote “depends upon” or “knows about”).
- In an Independent Domain, the red arrow is not present, and thus generally the blue arrows may aquire extra reponsiblities to compensate.
- Repositories (loosely as described by Evans or Fowler) are the main interfaces through which the upper part of the system interacts with the ORM layer.
- We’re mainly talking about data reads here, ie database queries.
[Notice that there are a lot of one way relationships between adjacent tiers; we developers have learned that the mssing depedencies are extraneous. But nonetheless, the reason for every missing (prohibited) relationship needs to be understood and justified. Its is not sufficient to reflexsively ban them to make the diagram "pretty" or "symmetric".]
Survey of Existing Views
- If domain objects depend on Repositories, they cannot be used in tiers/contexts where there is no open session to the persistence layer.
- Domain object depedency on persistence makes unit testing them more difficult
- In Jimmy Nilsson’s Applying Domain Driven Design, an overview diagram on page 116 depicts a Independent Domain, though he doesnt say why.
- In Fowler’s enterpise patterns book, the example code for Data Mapper uses a Co-Dependent Domain (ie Albumn Finder).
- In Javas J2EE 5 model, Entity Beans represent the Domain Model, Session Beans the service layer, and EntityManagers provide a gateway to the ORM layer. Sessions Beans can have the Entity Manager injected, but Entity Beans cannot, so clearly EJB 3 advocates the Independent Domain principle. Part of the reason, I think, is that J2EE promotes an Anemic Domain as a core principle, so they like to put business logic into their service layer, and make domain objects Dumb and Passive. Eg JBoss’s Bill Burke inEnterprise Java Beans 3.0: “Session Beans … are the appropriate place for business logic”. Its not my preferred architecture, but I’ll explore and evaluate the reasons they did that in another post.
- Bill Evans Domain Driven Design book supports a Co-Dependent domain, though he’s not entiely explicit and it required some careful reading to discern his positon.
- Some of my workmates favor an Independent Domain. I think the motivator is the appealing idea that a domain model should be able to exist in isolation. Certainly appealing, but is it workable in all cases?
Thats all Im aware of now. So Im left unsure if there are other any reasons. If anyone knows of more, good arguments for prescribing an Independent Domain, please send them to me.
I have yet to read any explicit argument outlining where Co-Dependent Domains are best – hence the need for this article.
When should Domain Objects access Repositories?
When they need to get references to other objects they interact with, and main alternative, traversal of the domain model relationships, doesn’t work well.
In an Independent Domain, where entities cannot query repositories, how will they get references to other objects?
- They have OR mapped relationships, set by the ORM layer when it loads the entity. If they need an object they dont have a reference to, they must traverse a path through intermediate relationships. This is the normal way that most entities communicate. Now, recall that object relations are unidirectional, in contrast to databases where with appropriate indexes, relations can be treated as being bidirectional. So there is the likelihood that our system’s domain model, even though fully connected, will not allow us to traverse everywhere within it, unless we deliberately create bidrectional relationships in the domain.
- They get passed them in method calls as parameters from the Service Layer. This just adds extra work for the calling code and leads to bloated method parameters.
Limits Of Domain Object Traversal
There are things you cannot do efficiently by traversing domain object pointers:
- Traversing a relationship with a high multiplicty, and then narrowing down the related domain object by some criteria. By High Multiplicity Relationships, I mean a many-to-one relationship between two entities, where the many side is numerous. It becomes impractical to traverse from the one side to the many side in the domain layer. Typically, we’re not interested in whole collection, just a small subset of them, so we dont want to have to load them into memory just to search through.
- Finding sums and similar aggregate functions of many small object. This is much more efficiently accomplished directly in the database.
Loose Coupling and Interface-Based Design
One of the reasons people advocate Indenpendent Domains is that they fear that referencing persistence- or service- layer classes will couple their domain to its application environment. It seems to me this confuses interface and implementation.
Your domain should access other layers through interfaces that are meaningful within the domain. When accessing the persistence layer, use a Repository interface that models the concept of “the collection all domain objects of type X in the world”, that could be backed a hashtable for all the domain knows. Similarly, when pushing events to the service layer, use a listener interface that does not reveal that the listener is outside the domain.
Linking the Domain to its Surrounding Layers
A co-dependent domain can be tricky to link to surrounding layers. Domain objects are usually created by the persistence framework (eg Hibernate), so injecting services into them before first use by the app requires interception of the create or load event.
Spring’s recomended approach require use of AspectJ class weaving to intercept the calling of domain objects constructors.
Most persistence frameworks should provide an on-load eent that can be hooked into (Hibernate does).
An alternative is to use a globally (ie statically) accessible Service Locator that the domain can use to lookup dependencies. It will work, but dependency injection is preferable.

Keith Patton said,
April 17, 2008 at 10:21 am
Excellent post, well done. I’ve been struggling with this issue for years in fact. I simply can’t understand how you don’t have a relatively anameic domain if you can only rely on the associations that are provided by the ORM (e.g. Hibernate). Of course a lot of stuff should be in the service layer, but where it makes sense domain logic should be domain logic and interfaces used with Dependency Injection to provide repository services to the domain. The domain can still be tested with a stub repository which is also tested so i don’t really see a big deal here in practiv. i like your term for it and have start to use it internally already;)
Garry McGlennon said,
June 23, 2008 at 6:02 am
Interesting entry and good to see soemone talking about it. I’m squarely in the indepenant domain category. A driving factor for me is that I look at most things from a service oriented perspective. To that end anything that travels accross the wire can’t have methods talk to the repository. I also find the breaking up of these two quite seperate concepts helps simplify both the code and the concepts of the applicaiton. I see there as three types of processes that the domain handles. 1) property validation, 2) entity validation and 3) process validation/processing. While pt 3 is still domain specific it aslo relies on multiple domain entities and ‘may’ vary depending on the application implementing the process (its less likely the first two will vary but its possible). This allows the domain to be used in multiple ways and extended easier for changing business processes without having to make the code overly complex. Ie you can seperate out business logic into seperate services (which btw are the only thing that understand pt 3) which deal with a particular use case. Obviously you’re not wanting to have a scattering of services doing a similar thing, so some type of strategy pattern may be used if it does get complex.
I’ve put a post on my blog around how to model the M:1 relationship which I find is something that gets little attention.
Larry said,
January 26, 2009 at 3:31 pm
Excellent post, i completely agree.
Without having ‘repository’ access in your domain objects, you are moving behavior out of that object. Isn’t that what an ‘object’ is all about, to have state and BEHAVIOR.
Testing of these domain objects isn’t an issue as you can have different implementations of the repositories.
It seems the reverse approach is great theory wise, but doesn’t hold up during implementation.