Aggregate root reference in another aggregate root - java

I currently have two aggregate roots - Customer and AddressBook. Both have some invariants that need to be protected. Customer has reference to AddressBook and I am not sure whether that is the correct way to model my domain because one cannot live without the other and since domain objects should be created using factories I feel like I should not allow creation of Customer without AddressBook and vice versa but obviously one needs to be created before the other. Hope it makes sense.
How should I address my problem?
Other question would be: can we create multiple aggregate roots in a single transaction? I've red that it should not be done in case of update.

I currently have two aggregate roots - Customer and AddressBook. Both have some invariants that need to be protected. Customer has reference to AddressBook and I am not sure whether that is the correct way to model my domain because one cannot live without the other
If they really don't make sense without the other, you may want to review the design to see if they are really part of the same consistency boundary.
Can we create multiple aggregate roots in a single transaction?
Technically, yes. It may not be a good idea.
When all of the logically distinct aggregates are stored together, then creating them in a single transaction is straightforward.
But that also introduces a constraint: that those aggregates need to be stored "together". If all of your aggregates are in the same relational database, an all or nothing transaction is not going to be a problem. On the other hand, if each aggregate is persisted into a document store, then you need a store that allows you to insert multiple documents in the same write.
And if your aggregates should happen to be stored in different document stores, then coordinating the writes becomes even more difficult.
I would like to create closely associated AddressBook with him.... Maybe a domain event would be a more suitable option?
Perhaps; using a domain event to signal a handler to invoke another transaction is a common pattern for automating work. See Evolving Business Processes a la Lokad for a good introduction to process managers.

Related

should dao (or perhaps repository) take id's or entities as arguments

In our code base we make extensive use of DAOs. In essence a layer that exposes a low level read/write api and where each DAO maps to a table in the database.
My question is should the dao's update methods take entity id's or entity references as arguments if we have different kinds of updates on an entity.
For example, say we have customers and adressess. We could have
customer.address = newAddress;
customerDao.updateCustomerAddress(customer);
or we could have
customerDao.updateCustomerAddress(customer.getId(), newAddress);
Which approach would you say is better?
The latter is more convenient since if we have the entity we always have the id, so it will always work. The converse is not always the case though, but would have to be preceded with getting the entity before performing the update.
In DDD we have Aggregates and Repositories. Aggregates ensure that the business invariants hold and Repositories handle the persistence.
I recommend that Aggregates should be pure, with no dependencies to any infrastructure code; that is, Aggregates should not know anything about persistence.
Also, you should use the Ubiquitous language in your domain code. That being said, your code should look like this (in the application layer):
customer = customerRepository.loadById(customerId);
customer.changeAddress(address);
customerRepository.save(customer);
I assume your question is
Which approach of the two is better?
I would prefer the second approach. It states clearly what will be done. The update object will be freshly loaded and it is absolutely clear that only the address will be updated. The first approach leaves room for doubt. What happens if customer.name has a new value aswell? Will it also be update?

Global access to objects; When to use Domain Driven Design Repositories

I've been following DDD principles (following the Eric Evans book on the topic) however I recently started re-reading the book and noticed that I appear to have strayed from one of the principles for repositories...
"For each type of object that needs global access, create an object
that can provide the illusion of an in-memory collection..."
I've strayed from this in that I create a repository for every aggregate and have found that this has suited me well. Even when an aggregate is itself associated with another aggregate it's a simple matter of referring to the associated aggregate's repository during creation of the entity (usually inside a factory).
The benefits of doing this that I've found are when performing operations such as caching in my repositories. It also really simplifies the divide between object creation/persistence and the domain.
Can somebody give me an example of where this "Global access" is not appropriate to help me understand where I've gone wrong.
I believe you are using wrong terms... Aggregate can't contain other aggregate. You probably have an association between those aggregates.
In any case, every aggregate should have repository, otherwise you are doing something wrong. Also it's better to use repository to load aggregate instead of association from other aggregate. If you keep your association (probably because your ORM makes it easy) you didn't split aggregates completely.

Aggregate objects in DDD

Can I use the same aggregate class as a member in other classes?
And if yes would the class that contains the aggregate enforce access etc on that?
Let say you have a User class. Then a class named LogBook and at last a class named Log/Post (something down that alley). The LogBook would be an aggregate root for the Log/Post class and the User would be the overall aggregate in my example. Now, would the User class contain methods for adding log-posts etc? You would make one method in the User class that invokes LogBook class which has a method that does all the logic for actually adding a log.
Or, is a aggregate ALWAYS on top of the hierachy? No nesting.
Here is a nice definition of an Aggregate:
Definition: A cluster of associated objects that are treated as a unit
for the purpose of data changes. External references are restricted to
one member of the Aggregate, designated as the root. A set of
consistency rules applies within the Aggregate's boundaries. Problem:
It is difficult to guarantee the consistency of changes to objects in
a model with complex associations. Invariants need to be maintained
that apply to closely related groups of objects, not just discrete
objects. Yet cautious locking schemes cause multiple users to
interfere pointlessly with each other and make a system unusable.
[DDD, p. 126] Solution: Cluster the Entities and Value Objects into
Aggregates and define boundaries around each. Choose one Entity to be
the root of each Aggregate, and control all access to the objects
inside the boundary through the root. Allow external objects to hold
references to root only. Transient references to the internal members
can be passed out for use within a single operation only. Because the
root controls access, it cannot be blindsided by changes to the
internals. This arrangemens makes it practical to enforce all
invariants for objects in the Aggregate and for the Aggregate as a
whole in any state change. [DDD, p. 129]
I don't think you want the User class reaching into the LogBook's aggregated objects without going through the LogBook class. However, accessing the LogBook from User seems OK.
I think the internals of an aggregate are allowed to hold references to the root of other aggregates. But each aggregate is responsible for enforcing its own boundaries. There is nothing stopping other objects from accessing the "referenced" aggregate completely outside of the first one - i.e. I don't think that nesting or ownership is implied just because one aggregate references another.
In your example, it seems like LogBook would fit better as an aggregate, controlling access to posts. Trying to shoehorn this into a larger User aggregate seems to be an awkward factoring of responsibilities.

Which layer do I 'hydrate' object graphs?

I have a persistence layer that serves data to many clients. I also have a table structure that is normalized, which means values are spread across tables. I want to design my persistence service to ensure services that depend on it do minimal round trips: not more than one, if possible.
Given this, what should I focus on for an elegant solution?
1. Do I ensure the clients can indicate the portion of the object graph they want during the fetch? (thereby reducing round-trips) [eg: fetch(parent, list<child-object-name>) ]
2. Do I ensure I provide common methods such for hydrating portions of the object, along with basic fetches? [eg: hydrate(parent, list<child-table-name>)]
3. Do I provide basic information to start with (for example, object graph to depth 1 only / only look-up-table objects,) and the rest only upon request?
I understand, there are many many discussion on the net, with very good information. I did read a few as well:
* http://forum.springsource.org/archive/index.php/t-23439.html
* How can I access lazy-loaded fields after the session has closed, using hibernate? (answer by Paul Adamson)
* Deep Object Graphs Hibernate
however, most of the answers hover about 'do what suits you best'. What do programmers usually do in this situation?
Don't make a generic one-size fits-all persistence layer. Write persistence methods specifically for the functional use-cases you're implementing.
While doing it, you're probably going to meet cases where a persistence method, or some part of it, can be reused across two or more use-cases. This will probably force you to rename the method to make it more generic (less coupled to one specific use-case), or refactor to extract the common part. But if you want the best performance for your app, you're going to need specific queries for specific use-cases.

DAO design pattern and using it across multiple tables

I'm looking for feedback on the Data Access Object design pattern and using it when you have to access data across multiple tables. It seems like that pattern, which has a DAO for each table along with a Data Transfer Object (DTO) that represents a single row, isn't too useful for when dealing with data from multiple tables. I was thinking about creating a composite DAO and corresponding DTO that would return the result of, let's say performing a join on two tables. This way I can use SQL to grab all the data instead of first grabbing data from one using one DAO and than the second table using the second DAO, and than composing them together in Java.
Is there a better solution? And no, I'm not able to move to Hibernate or another ORM tool at the moment. Just straight JDBC for this project.
I would agree with your approach. My DAOs tend to be aligned more at the object level, rather than from a DB Table perspective. I may manage more than one object through a DAO, but they will very likely be closely related. There is no reason not to have SQL accessing two tables living in one DAO.
And for the record, I have banished the acronym DTO from my vocabulary and code.
Ideally, how you store your data in a database, and then how you access them, should be derived from the nature of the relationship among the domain entities in your domain model. That is, Relational Model should follow from Domain Model. For example, if you have two entities, say, User and Address.
Scenario #1: Address are never accessed independently, they are always an attribute of User.
In this case, Address is a Value Object and User is an Entity, and there are guides on how to store this relationship. One way is to store Address attributes of Address alongside of attributes of User, in a single table. In this case, UserDao will handle both objects.
Scenario #2: Address can be associated to a User, but also can be separate on its own, an entity.
In this case, an approach different from the first one is needed. You may have a separate DAO and table for the Address type.
My point is, that more often this important idea is ignored that Domain Model should be the core of the application, driving other layers.
For instance, if your domain model is properly define and you are well aware of the type of entities you have and the relationship among them, then your persistence (relational tables and their relationships, your DAOs, etc) will evolve as a very logical consequence of what you have in the domain model.
In other words, if you spend some time studying your model, you will be able to trace your problem in determining how to organize your DAOs to a place in the domain model. If you can clearly define the type of the objects and the nature of relationship among them in the domain model, it will, help you resolve your problem in DAL layer.

Categories