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.
Related
I have three tables on a database, and one old and good query that joins the interesting columns for the usecase on a DTO object after use a RowMapper. Classical Java approach.
But I am wondering, how can I convert this into a DDD implementation? How can I use entities for solve the problem without having 3 separated queries to create the models with it's fields, and then create a DTO just for create the object with the desired columns?
What I am missing? Or should be better the already implemented way?
You cannot convert that model to DDD.
DDD is about creating a business model in a separate layer: the domain layer. The purpose of this layer is to verify that any state-changing operations does not violate your business rules. How you model your domain entities must be driven by the use case you are handling, not how the data is stored: the domain layer is said to be persistence agnostic. It doesn't matter whether the data is stored in one or multiple stores, RDBMS, nosql, files, etc ... that's ther purpose of the infrastructure layer.
Domain object are read by a class called a repository. The repository behaves like an in memory collection of domain object, but actually re-hydrates objects from the persistence store(s). It operates as a mediator between your persistence model and your domain model. Since models may differ, the repository can flatten relations, join data from different sources, and ignore some columns if needed.
When querying your state, you don't need to use the domain layer at all. The purpose of that layer is to validate state-changing operation, business-wise, but this is unnecessary when querying the state. In that situation, you can implement classes, called mediators, that will query your database and produce presentation layer DTO. Like the repositories, mediators are adapters between your persistence model and your presentation model. It can join data from multiple persistence stores, flatten relations, and ignore columns as well.
Whether to use an ORM, or not, for accessing the database, is an implementation detail of your infrastructure layer. It has nothing to do with domain modeling, which is about your use cases and business rules validation.
I am wondering if JPA entity and DDD entity should be the same class?
I can see in examples that it is a common practice, but doesn't it violate single responsibility principle?
I believe this to be common practice due to a level of convenience but it's not particularly clean design. In most cases it's coincidental that the JPA entities match, or are at least close enough, to domain objects.
JPA is an abstraction to the persistent data layer and its core focus is providing an object to relational data mapping. The JPA entities therefore really only represent object hierarchies of the data model.
It may well be that your domain objects consist of only elements that are represented and stored within a persistent data store and this would feel somewhat like duplication if creating both domain and JPA entities that contain the exact same data structures.
True domain objects live at the center of the application's architecture where all dependencies point towards them and this would also include the data layer. I would always recommend this approach purely as it clarifies the actual intent for the architectural boundaries.
Edit.
To answer your second part of the question on SRP violation in JPA - it depends. The responsibilities (in SRP) do tend to match relational tables since we tend to logically group related data together (think Account table, or Contact table). This does fall down in JPA more often though when thinking about relationships (Employee -> Salary).
I am wondering if JPA entity and DDD entity should be the same class? I can see in examples that it is a common practice, but doesn't it violate single responsibility principle?
You may want to review Classes vs Data Structures, by Robert Martin.
I would normally expect JPA entities to be "anemic bags of data"; they are essentially messages written in the past to be consumed in the future.
Domain Model Entities, on the other hand, are not anemic - they have direct understanding of how to mutate their own data structures in accordance with the rules of the domain in which they serve.
In the DDD book, Evans describes using the "factory" pattern to create an instance of a domain entity from raw data. That pattern fits equally well with creating a domain entity from a jpa entity.
The transformation in the other direction -- taking a domain entity and extracting from it the data you need to save, is not clearly addressed, but the mechanics are the same. You read data out of your domain entity, and write it into your jpa entity (whether or you writing into a new jpa entity, or updating one that already exists, will depend on the details of your persistence strategy).
You aren't guaranteed to make a mess if you try to make the two entities "the same", but there are definitely different concerns.
For example, our persistent representation of data is expected to have a life cycle that spans many releases, new versions of our domain model are supposed to be to work our previously stored data. At the same time, we should be able to change the data structures that we use inside the domain model freely. Semantically, it's the same information, but the pressures on structure and organization are very different.
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.
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?
I am using MVC pattern in my web application. In which I have three layers
Control Layer
Manager Layer
Dao Layer
And I am using DTOs from control layer to manger and then to Dao layer and same as opposite.
My question is that what is the main purpose of DTO?
Can I use DTOs to map our relational database table or should I go with 'Bean'?
If I use DTOs between layers then how can I represent a database table in an object because DTOs among layers can contain properties which are not related to the database table.
There is no problem in using DTOs and map them to your database tables. But you'll have to do the mapping by yourself (using JDBC, Spring JDBC, etc).
Another option is to use an ORM to do the mapping of your DTOs to database. You can even create properties that are not mapped to your tables. Take a look at JPA.
The choice between those two options is something personal. The first will be more laborous at first, while the second option have a bigger learning curve. If you are well versed into SQL, I would go with JDBC.
My question is that what is the main
purpose of DTO?
The main purpose of a DTO is to transmit data between two layers. It has no real functionality other than to act as a basket for shipping data.
That's why they call it a Data Transfer Object.
Can i use DTO's to map our relational
database table or should i go with
'Bean'?
Whether you decide to use JavaBean formatted accessors or your own accessors really doesn't matter with a DTO. Both sides of the transfer must be in agreement; but, if you have a setName(...) setter or a name(...) setter it will not affect functionality.
Although it may not matter in a functionality sense, it is best to stick to established naming conventions for ease of revisiting the code and lack of confusion when training new maintainers. Also, a few libraries might assume you are using bean conventions (or require them). If you are uncertain, best to stick with standard JavaBean conventions, as your new conventions are probably not as tested (or as formal).
If i use DTO's between layers then how
can i represent a database table in
object because DTO's among layers can
contain properties which are not
related to database table.
DTOs have nothing to do with database tables. Don't make your DTO look like your database table unless it's the most natural thing to do.
The main purpose of DTO's is to reduce the overhead when transferring data across layers.
If you didnt have a DTO, what you would have is a class containing data as well as logic which would be getting passed across layers. Using DTO's ensures that you pass only what is needed i.e the data across layers.
Definitely, you do have the option of mapping your DTO's to your database tables and having the bean design which more closely represents the domain objects.
That is one way of doing it.
Conversely, depending on your database design, your DTO's could be more in line with your actual business entities - just without the logic
My question is that what is the main
purpose of DTO?
Like the expansion (Data Transfer Object) implies, DTOs are meant to transfer structured data across various tiers. DTOs enable you to decouple the protocol specific implementations that represent data, so that data from different sources can be abstracted before communication across tiers.
For example, DTOs will allow you to decouple the data present in a HttpServletRequest object from its internal storage, so that you can send the data to a service in the business logic layer. The same applies for DTOs used to abstract the results obtained from a SQL query and residing in a ResultSet object. In short, DTOs allow you to transmit data without holding onto the source - you can forget about the HTTP response and the JDBC connections, while you work on the data.
Can i use DTO's to map our relational
database table or should i go with
'Bean'?
You can adopt the second approach of using Beans. In fact, with JPA you do not require your DTOs at all. The JPA managed beans themselves represent data in various tables, and can be de-linked from the database state, so that you can use them for data transmission.
If i use DTO's between layers then how
can i represent a database table in
object because DTO's among layers can
contain properties which are not
related to database table.
That depends on how you want to couple the DTO with the database table. It is preferable to have a one-to-one mapping between the DTO and the database table, and choose another DTO for the purpose of transmitting properties not related to the table. After all, DTOs like every other object should have a single responsibility. If the responsibility is to reflect a database table, then it should contain other "irrelevant" properties.
To extend the recommendation of using JPA in this context, it is poor design to have unrelated attributes in a JPA entity, especially when that unrelated attribute should be marked as transient and adds no value to the behavior of the entity.