Questions about DAO pattern
Hi,
I am a junior programmer and I am trying to understand somewhat more about best practices and design patterns.
I am looking for more information regarding the DAO pattern, not the easy examples you find everywhere on the internet, but actual implementations of real world examples.
Questions:
1) Does a DAO always map with a single table in the database?
2) Does a DAO contain any validation logic or is all validation logic contained in the Business Object?
3) In a database I have 2 tables: Person and Address. As far as I understand the DAO pattern, I now create a PersonDAO and an AddressDAO who will perform the CRUD operations for the Person and Address objects. PersonDAO only has access to the Person table and AddressDAO only has access to the Address table. This seems correct to me, but what if I must be able to look up all persons who live in the same city? What if I also want to look up persons via their telephone numbers? I could add a findPersonByCity and findPersonByTelephoneNumber method to the PersonDAO, but that would result in the PersonDAO also accessing the Address table in the database (even though there already is an AddressDAO). Is that permitted? And why?
I hope someone can help me out.
Thanks for your time!
Jeroen
[1314 byte] By [
Jeroen.VSa] at [2007-11-27 3:32:06]

# 1
1) No. A DTO maps to a single table. A DAO contains the actual code to map one or more tables to one or more (or nested) DTO's.2) No. The business logic (validation is) should be allocated in the business tier.3) That is permitted. Why not then? Think pragmatic.
# 2
Thank you for your fast reply!
Some more questions:
1a) IMO it makes sense for DAOs to load nested DTOs since that corresponds to an optimized SELECT query using a JOIN. Is that correct?
1b) But does it also make sense to provide INSERT queries for multiple tables that already have their own DAO? IMO that would result in copying the same code in different classes, which is not a good practice IMO?
2a) Can I make DAOs that just load (nested or not) DTOs without providing Create Update and Delete operations? Those DAOs would be used to load certain VIEWS (like in database terminology) like discussed in question 1a).
2b) How would I name such DAOs? ViewDAO like for instance PersonViewDAO which has a findPersonWithAddresses(String personId) operation?
3a) As you can see I wish to structure my DAOs in what operations they provide, PersonDAO provides Create Read Update and Delete operations. PersonViewDAO provides more advanced Read operations but no Create Update and Delete operations. Is this a good practice, or am I just making alot more DAOs than I should?
3b) Should the findPersonByCity operation be in the PersonDAO or the PersonViewDAO? Or can it be in both?
As you can see I can use any pointers on how to organize my DAOs. Or is it a silly idea to try and do that?
Thanks!
Jeroen
# 3
1a) You can do that. Generally the DAO should return the object(s) which are associated with the DAO, regardless the parameters. For example Person person = PersonDAO.getPersonByAddress(address);
1b) Refractor to more backing/utility classes. Or create an universal DAO/ORM. Or use existing 3rd party ORM's, like Hibernate.
2) and 3) Depends on requirements. Basically you use PersonDAO to retrieve Person(s). But you can also widen that, for example UniversalDAO<Person> to retrieve Person. Also see 1a) and 1b).
# 4
Some more questions:
1) PersonDAO is meant to return Person DTOs, and you can use the full power of the relational database (or other datastores) to do that. This means:
1a) You can search all tables of the database to find the Person DTO you are looking for. For example searching the Address table to find all Person DTOs who live in "New York". Correct?
1b) You can use the PersonDAO to also load nested DTOs of Person DTO. Address DTO is nested in Person DTO, so I can write an operation to load all addresses as well (findPersonWithAddresses) using a SELECT with a JOIN. Correct?
1c) Alternative to 1b) is using the AddressDAO to load all Address DTOs for a certain personId. Correct?
2) Is it more performant to use 1 SELECT with a JOIN clause or lots of smaller SELECTs? It will always depend on the situation ofcourse, but I think that having 7 SELECTS with a JOIN is more performant to generate a webpage than having 50 small SELECTs? What do you think?
3) A DAO never uses another DAO right? So PersonDAO will never use AddressDAO or any other DAO. Correct?
4) It is the Business Object who will use all available DAOs to get a certain result. Correct?
Thanks!
Jeroen
# 5
1) Use the power of an well-indexed RDBMS to retrieve specific data in less possible SQL queries (however, don't overlook "less possible", benchmarking might be useful in this).
2) Each connection and statement costs time. Less is always better.
3) This is not actually true. If you can, rather do the joins right in the DB. Once when the DB has it's incapabilities, then you can use Java to act as intermediator.
4) Yes. Let it follow the Javabean spec: store the result in an encapsulated private variable with accessors. Then in the client-tier you can access the result by it's accessors.
# 6
Thanks for all these answers in such a short time! :d
Some more questions:
1a) Since DAOs can access the whole database, changing a table in the database can result in multiple DAOs needing to be changed as well. This means that the DAO pattern isnt designed to lay boundaries between tables (which I though before) but to seperate the database accessing logic from the rest of the program. Is this correct?
1b) A DAO doesnt have a narrow vision of just 1 table in the database, but can use all tables of the database. Is this correct?
2a) A DAO can use another DAO. This means PersonDAO can use AddressDAO and other DAOs as well? This creates dependancies on the other DAOs. Is this a best practise?
2b) Doesnt the Business Object act as a Java intermediator to compose the result?
3) If a DAO can use another DAO, does that also mean that a Business Object can use another Business Object? This will also create dependencies?
Thanks,
Jeroen
# 7
1a) Changing one table should result at least one DTO and it's DAO need to be changed. And the DAO pattern is indeed intented to separate data access logic from the business logic, so that you can reuse the same DAO class in many business logic classes.
1b) Depends on design requirements and use. Strictly you should map one table to one DTO. A DAO can handle multiple DTO's if you want.
2a) Best practice is to handle joins in SQL queries and keep relations in the database. There it is for. A DAO should only map between DTO's and the database.
2b) In the business layer you generally do the pre- and post-processing. I.e. validation and conversion where needed.
3) There are always dependencies. Java is OO. What should happen if Sun decide to change one of the behaviours of the java.lang.Object class for example? That's why you need to think twice about it.
# 8
Since I am asking you so much questions I raised the Duke Points to 10 for this thread :)
Some more questions:
1a) Strictly you map one table to 1 DTO, because the DTO is an image of that table. The table has foreign keys, which will be mapped to nested DTOs. Is that correct?
1b) A DAO can be used to fill up that DTO, and possibly but not necessarily also his nested DTOs. Is that correct?
2) Can I use the Business Object to assemble a DTO and his nested DTOs?
For example PersonBO uses PersonDAO.findPerson(String personId) and AddressDAO.findAddresses(String personId) to get the Person DTO and his nested Address DTOs and returns the composed Person DTO. Is this correct or is this not the function of the Business Object?
3) Does every DAO need to have a Business Object? IMO I think they do, how else can you validate a DTO before inserting it in the database? PersonBO will validate Person DTO and AddressBO will validate an Address DTO. Is this correct?
Thanks,
Jeroen
# 9
1a) Correct.
1b) That is indeed not necessarily. It may also depend on query parameters. For example Person personWithoutAddress = PersonDAO.getPersonByAddress(address, false); where 'false' indicates that the DAO doesn't need to fill the nested Address DTO.
2) It can. But if PersonDAO supports loading of Address in Person I'd rather to use it and then retrieve the address in the BO using person.getAddress().
3) That is the meaning of a three-tier application: Client - Business - Data. Here the primary goal of a DAO is to map the DTO's to the database without the need to care about the actual values. Nothing more, nothing less.
# 10
Some more questions :)
1) So I am correct to assume that each DAO has a BO (Business Object) which will validate the corresponding DTO?
2a) Where will transaction management (beginTransaction, commit, rollBack) be? IMO it cannot be in the DAO layer. Since you say one Business Object can use another Business Object to get a result, transaction management cannot be in the Business layer. Am I right to assume this?
2b) Where would transaction management be? In the layer above the Business layer? What is the name of that layer?
3) What is the relation between a Usecase and an operation of a Business Object?
Thanks!
Jeroen
# 11
1) Your view is from the wrong side. Like rephrase as follows: "Each BO will validate the corresponding DTO for each DAO". DAO's don't need to care about this. Ask yourself: are you planning to invoke the DAO's as stand alone applications? No, there the Client Application is for.
2a) Transactions should live as short as possible. So put it in the DAO. You can consider conneciton pooling to reuse connections which will give a speedup.
2b) Actually in the DAO. If you're thinking that you have to copypaste transaction code in all DAO's, then you're wrong, put it in a DAO utility class. All DAO's and those utility classes together can be called "Data Access Layer".
3) An operation is a part of an usecase. One usecase describes all operations from start until end.
I would mention, if it gets bigger and bigger, consider 3rd party DAO/ORM solutions, like Hibernate. It is really worth the effort. But writing it all yourself is good for your experience and understanding :)
# 12
That is exactly what I am trying to do. I am writing it all myself to get a better understanding of it.
Please bear with me, because there are some things I dont understand in your previous answer.
1) Each BO validates his corresponding DTO and exposes operations to persist that DTO. Each DTO will be persisted in the database via his corresponding DAO. So this would be:
- in PersonBO
public void save(PersonDTO personDTO) {
this.validate(personDTO); // does not validate the nested address DTOs
this.personDAO.save(personDTO); // does not save the nested address DTOs
}
- in AddressBO
public void save(AddressDTO addressDTO) {
this.validate(addressDTO);
this.addressDAO.save(addressDTO);
}
Am I viewing it from the right side now?
2) Imagine a form designed to insert a new person in the database, it contains all fields for the Person DTO and 2 Address DTOs.
How would I do this using my Business Objects?
This is how I see it:
// fill the DTOs
daoManager.beginTransaction();
try {
personBO.setDao(daoManager.getDao(PersonDAO.class));
personBO.save(personDTO); // save 1
addressBO.setDao(daoManager.getDao(AddressDAO.class));
addressBO.save(personDTO.getAddress(1)); // save 2
addressBO.save(personDTO.getAddress(2)); // save 3
daoManager.commit();
}
catch(Exception e) {
daoManager.rollBack();
}
If I insert the transaction management inside the DAOs, I can never rollback save 1 when save 2 or save 3 fail.
It can be that I am viewing it all wrong, please correct me if that is the case.
Thanks!
Jeroen
# 13
1) You can use multiple DAO's per BO. Generally you attach one BO to one input form at the Client side. Or if you have only a very little set of little forms, then one BO for all can be enough. You can always split and refractor when it gets bigger.
2) Like I said earlier, you can save the nested AddressDTO in the PersonDAO. You can eventually add a boolean toggle to indicate whether PersonDAO should save nested DTO's or not.
# 14
1) You are saying that a BO can have many DAOs, this implies that that BO will also hold all validation logic for the corresponding (nested) DTOs of those DAOs?
2) The example of Person and Address is simple cause the nesting level is 1 deep, but what if the nesting level is 4 deep? You are still going to use 1 BO for all those nested DTOs?
3) How are you going to do a rollback if the transaction management is inside the PersonDAO and AddressDAO?
4) As far as I know a transaction may span several operations of several Business Objects, so that would mean the transaction management lays after the Business layer like I described in Question 2 of my previous post. Or am I incorrect?
I know Hibernate and other ORMs make life lots easier, but I first want to learn it the hard way, so I can fully understand it, and later on fully appreciate the services those ORMs give me.
Thanks.
Jeroen
Ps. Maybe you know of an example that can help me better understand the relationship between DTO-BO-DAO?
# 15
1) The BO validates the client input, not the DB output. The content inside the DB should always be validated before inserting.
2) Nesting level shouldn't matter, it's all about the parent DTO.
3) and 4) I think this example clears out enough.
Example:
Client (assuming a JSP page with input fields)<input type="text" name="input1" />
<input type="text" name="input2" />
<input type="text" name="nestedInput1" />
<input type="text" name="nestedInput2" />
BO// first retrieve and validate input1, input2, nestedInput1, nestedInput2, then populate DTO:
SomeDto someDto = new SomeDto();
someDto.setInput1(input1);
someDto.setInput2(input2);
NestedDto nestedDto = new NestedDto();
nestedDto.setNestedInput1(nestedInput1);
nestedDto.setNestedInput2(nestedInput2);
someDto.setNestedDto(nestedDto);
// Save DTO
SomeDAO.save(someDto);
SomeDAOMap DTO to SQL queries.
Get connection.
Invoke SQL queries.
Commit connection, if error then rollback.
Close connection.
# 16
The Hibernate Framework takes care of most of this. If you are studying, you should also learn how to implement EJB 2.0.
If you learn how to design hand-written DAO using JDBC, and then learn how to use CMP and Enterprise JavaBeans (version 2), then you will greatly appreciate Hibernate and JPA.
Or, you can start studying Hibernate as soon as possible, and still fully appreciate it.
# 17
I want to understand how the DAO pattern works, without having to rely on certain language specific frameworks or technologies. It is true that Java has EJBs and Hibernate, and it is true that they make life alot easier, but I want to understand how to implement the DAO pattern myself so I can use it in whatever language I choose.
BalusC has helped me gain alot of insight already, but there are still some things that arent quite clear to me.
Yesterday evening I tried to process all information given to me, but while doing so, some more questions popped up.
I am going to try studying some more before I ask additional questions, so keep monitoring this thread ;)
Thanks,
Jeroen
# 18
Good point. Take note that, in regards to the Data Access Object design pattern, the format of the data is the most important variable that effects how the pattern is implemented, i.e the algorithms and control structures of the behaviors.
In this thread, it seems like the data is in relational format, and the DAO design is based on processing data in this format.
If the data is in an XML-based format, then the implementation of the Data Access Object design pattern would be quite different.
If the data is in a CSV-based format, then the implementation of the Data Access Object design pattern would be quite different.
If the data is in a binary format, then the implementation of the Data Access Object design pattern would be quite different.
If the data is only accessible via web services, then the implementation of the Data Access Object design pattern would be quite different.
My point is: Same design pattern, different implementations based on data format.
Good luck!
# 19
> 1) No. A DTO maps to a single table. A DAO contains
> the actual code to map one or more tables to one or
> more (or nested) DTO's.
That first part is a bit extreme. A DTO might contain a collection of other DTOs. So conceptually the relationship might be one to one, the implementation reality might be different.
> 2) No. The business logic (validation is) should be
> allocated in the business tier.
Incorrect.Business logic to some extent will span the entire enterprise.
Thus the database will require that an order does not exist without a customer.
Thus the DAO layer can require that a customer name exists before it attempts to insert a new customer.
Thus the GUI layer can require that the customer name actually looks like a name rather than something like a url.
That doesn't mean that all of the business logic exists in all layers but rather that the reality of implementation means that business logic will impact all layers.
# 20
> That first part is a bit extreme. A DTO might
> contain a collection of other DTOs. So conceptually
> the relationship might be one to one, the
> implementation reality might be different.
Relationships are actually definied in the database table. And the DTO indeed should just map them. But if you mean that I was forgotten to mention one-to-many relationships in form of a Collection<Dto>, you're right.
> Incorrect.Business logic to some extent will span
> the entire enterprise.
>
> Thus the database will require that an order does not
> exist without a customer.
>
> Thus the DAO layer can require that a customer name
> exists before it attempts to insert a new customer.
>
> Thus the GUI layer can require that the customer name
> actually looks like a name rather than something like
> a url.
>
>
> That doesn't mean that all of the business logic
> exists in all layers but rather that the reality of
> implementation means that business logic will impact
> all layers.
Technically you're right. But personally I should keep validation and conversion as much as possible in the business layer. This layer is the only layer which knows something about the database *and* the client.
Not to forget to mention, if you do all the validations in the DAO and then on long term replace the DAO by an ORM, which is generally poorly configureable regarding to validation and errorhandling, you will have to do more rework in the business layer.
# 21
>
> Technically you're right. But personally I should
> keep validation and conversion as much as possible in
> the business layer. This layer is the only layer
> which knows something about the database *and* the
> client.
As an ideal it is ok, as long as one understands that the reality means that business rules will appear in other layers and must appear there. One shouldn't convolute a design nor ignore simple and normal possibilities (like table contraints) because that is an ideal.
>
> Not to forget to mention, if you do all the
> validations in the DAO and then on long term replace
> the DAO by an ORM, which is generally poorly
> configureable regarding to validation and
> errorhandling, you will have to do more rework in the
> business layer.
Yes but I was pointing out that the business layer could do validations, not that it was the sole place that any specific validation might occur.
# 22
Thanks to all contributors of this thread!You made me realize that I have a lot of studying ahead of me :p- Jeroen
# 23
> > 1) No. A DTO maps to a single table. A DAO
> contains
> > the actual code to map one or more tables to one
> or
> > more (or nested) DTO's.
>
> That first part is a bit extreme. A DTO might
> contain a collection of other DTOs. So conceptually
> the relationship might be one to one, the
> implementation reality might be different.
I was thinking more along the lines that if you follow this, a change to the database table might require that the DTO change for no other reason. That doesn't make a lot of sense to me.
I think that if you were designing the code and the database schema together, then you'd probably end up with this in the beginning and that's fine. If you are building an OO design to work with an existing database schema, I would not let the database schema dictate my class designs. You still might end up with that relationship but it shouldn't be a requirement, IMO. I've seen that approach go wrong really quickly.
# 24
> You made me realize that I have a lot of studying
> ahead of me :p
You will not become an adequate software engineer through study only. There is no career that can be mastered through study alone. Think if the pilot of an airplane you were riding in just studied piloting but had no experience flying planes.
Studying is necessary but not sufficient.
# 25
What you say is absolutely true.
I have an additional question if I may. While researching information about the DAO pattern I came across VO (Value Object) and DTO (Data Transfer Object).
1) What is the difference between VO and DTO?
2) When and where do I use VO and when and where do I use DTO?
3a) Can a VO contain nested VO's?
3b) Can a DTO contain nested DTO's?
Thanks!
# 26
A VO is a Value Object, just for pure "storage" inside the JVM. The DTO's have the same base design (private fields with public accessors). The difference is that the DTO's are been used at least to pass data between the data layer and the business layer. And sometimes thoroughout to the client layer.
In case of the VO's -at least, in the perspective where the 'VO' term is been used- there is no DAO involved whatsoever. For example a Mail object with fields/accessors for smtp, subject, sender, etc and which can be used by a Mailer utility class which sends this Mail VO.
Sometimes VO's are also been used when a method takes so much parameters or want to returns more than one value. Those can be mapped through VO's then.
It's just all about it's functionality :)
# 27
Thanks for the speedy reply!So when using DAO's, I always use DTOs? Correct?As far as postfixes go, do you think it is usefull to name each DTO with a 'DTO' postfix (PersonDTO) or do you think it is unnecessary (just use Person)?
# 28
It's your design choice. I use it in the package name, for example net.balusc.webappname.data
# 29
> So when using DAO's, I always use DTOs? Correct?
Not always. It depends on your design. For example, you can have a DAO in an application that gets data from a database table and will return an integer.
public class SecretCodeDAO {
public int getCode() {
....
}
}
Or, a DAO that gets data from a database table and returns data as an XML fragment.
public class CustomerDAO {
public String getCustomerRecordXML(String id) {
....
}
}
These two examples of DAO's do not have DTO's.