Questions on DAO design
This is the first time I used DAO design.
I have a machine
class and each machine has a few parts
.
How should I design the DAO? Especially regarding the inner parts
.
Should I create a DAO for machine
and for part
and put the PartDAO
as an atribute of MachineDAO
so that I can populate the Machine's parts with the help of PartDAO
Or is it better to retrieve the parts directly when retrieving machine by JOINING the 2 tables (inside MachineDAO).
Or are there other best practices regarding DAO design?
Please help me,
Thx in advance,
David Limanus
[652 byte] By [
Klincia] at [2007-10-3 0:19:37]

dont think it matters but what I try to do is keep one dao dealing with just one table. All instances are partDAO should be created out of static factory method on PartDAO. MachineDAO will have to do a join or some such to get all PartDAOs that belong to it depending on how you formulated your tables. But the Machine class should ask the MachineDAO for the PartDAOs. And the Machine class then will pass the PartDAO through the Part class in order to have instances of Part.
The Machine class ultimately will hold instances of Part class and an instance of MachineDAO.
Thats how I did it because it worked for my architecture.
> dont think it matters but what I try to do is keep
> one dao dealing with just one table.
No. That's a table mapper.
One DAO should deal with one object, including all its child 1:m and m:n relationships.
> All instances
> are partDAO should be created out of static factory
> method on PartDAO. MachineDAO will have to do a join
> or some such to get all PartDAOs that belong to it
> depending on how you formulated your tables.
Inefficient by design: suffers from the (n+1) query problem.
> But the
> Machine class should ask the MachineDAO for the
> PartDAOs. And the Machine class then will pass the
> PartDAO through the Part class in order to have
> instances of Part.
>
> The Machine class ultimately will hold instances of
> Part class and an instance of MachineDAO.
>
> Thats how I did it because it worked for my
> architecture.
It "works", but it's not the best or only way to do this. And there's nothing in the DAO pattern that demands it.
It suggests that there's one object per table, which usually means a less than optimal object design.
Too many problems to mention.
%
Thx for all the replies, but I still can't understand your suggestions.
> One DAO should deal with one object, including all
> its child 1:m and m:n relationships.
Is this means that I should only have MachineDAO without PartDAO and the Machine class returned will be having it's Part collection automatically populated by using JOIN inside the MachineDAO.getMachine(Long id) ?
> Too many problems to mention.
What do you mean?
Thx in advance
David Limanus
> Thx for all the replies, but I still can't understand your suggestions.
You'll have to start reading more then. I'll recommend Martin Fowler's "Patterns of Enterprise Application Architecture".
> Is this means that I should only have MachineDAO
> without PartDAO and the Machine class returned will
> be having it's Part collection automatically
> populated by using JOIN inside the
> MachineDAO.getMachine(Long id) ?
Yes. That's what would be done for you if you implemented the DAO in Hibernate and mapped it with its 1:m relationship.
> What do you mean?
The biggest mistake is letting the relational model determine your object model. One object for every table leaves out a lot of important object oriented features (e.g., tables don't inherit or have polymorphism). Your object model should probably be finer grained than your relational model.
There's the inefficiency of the (n+1) query model.
What else do you need to be convinced?
%
> You'll have to start reading more then. I'll
> recommend Martin Fowler's "Patterns of Enterprise
> Application Architecture".
Ok, I'll read it. Thanks
> Yes. That's what would be done for you if you
> implemented the DAO in Hibernate and mapped it with
> its 1:m relationship.
Actually I've consider Hibernate but my project schedule is tight. I'm affraid I can't learn it in time. That's why I'm trying to use Spring's JdbcTemplate in DAOs.
The problem with this approach(auto populate using JOIN) is how far should I fetch all the object along the class diagram.
Do you have suggestions on this?
Thx in advance,
David Limanus
> > You'll have to start reading more then. I'll
> > recommend Martin Fowler's "Patterns of Enterprise
> > Application Architecture".
>
> Ok, I'll read it. Thanks
>
> Yes. That's what would be done for you if you
> implemented the DAO in Hibernate and mapped it with
> its 1:m relationship.
>
> Actually I've consider Hibernate but my project
> schedule is tight. I'm affraid I can't learn it in
> time. That's why I'm trying to use Spring's
> JdbcTemplate in DAOs.
If you're using Spring you're in good shape.
You just a have to write the mappings in such a way that you populate the child objects.
> The problem with this approach(auto populate using
> JOIN) is how far should I fetch all the object along
> the class diagram.
How deep is the object graph?
> Do you have suggestions on this?
I'd have to know more about your particular situation. I just learned that you're using Spring.
%
> > dont think it matters but what I try to do is keep
> > one dao dealing with just one table.
>
> No. That's a table mapper.
>
> One DAO should deal with one object, including all
> its child 1:m and m:n relationships.
Right sorry. When you think from the user of the DAO yes, one DAO should deal with one object. Then when you start implementing the DAO, You will try to reduce the overall number of tables. But its true that I may have 3 different DAOs that access the same table. Also, that I have one DAO that uses multiple tables.
Actually what I tried was to handle one table from one class file. That didn't really work either because of the joins and subqueries.
>
> > All instances
> > are partDAO should be created out of static
> factory
> > method on PartDAO. MachineDAO will have to do a
> join
> > or some such to get all PartDAOs that belong to it
> > depending on how you formulated your tables.
>
> Inefficient by design: suffers from the (n+1) query
> problem.
Could you explain that problem? It seems to work well for me and is easily managed.
> Right sorry. When you think from the user of the DAO
> yes, one DAO should deal with one object. Then when
> you start implementing the DAO, You will try to
> reduce the overall number of tables.
I don't agree - the number of tables should be designed according to the data's needs and normalization rules, and the objects according to the problem's needs. Then you map one to the other. I don't understand what you mean by "reduce the overall number of tables".
> But its true
> that I may have 3 different DAOs that access the same
> table.
Meaning that one may access the table directly and others JOIN to it? Yes.
> Also, that I have one DAO that uses multiple tables.
Meaning JOINs? Yes.
> Actually what I tried was to handle one table from
> one class file. That didn't really work
> either because of the joins and subqueries.
> > Inefficient by design: suffers from the (n+1)
> query
> > problem.
>
> Could you explain that problem? It seems to work
> well for me and is easily managed.
If you measure the performance and find that it meets your service level agreement, then it "works".But it depends on the number of Parts a Machine has, right? If you do one query for each Part, that means one network roundtrip for each one. As the number of Parts gets large, so does the number of network roundtrips. Since network latency is one of the biggest bottlenecks in your app, the more of them you do, the worse your performance.
A Machine that requires a small number of Parts might perform fine, but if the number increases you might find that performance is unacceptable. Maybe yours is "working well" because your Machines are simple.
%
Maybe there was a misunderstanding. The MachineDAO returns instances of the PartDAO. If you ask
PartDAO [] machine.getAllParts();
it will return all the parts belonging to that machine. That is a single query to get the list of parts. What it actually returns is a list of part IDs. then a PartDAO is created and fed the part ID and returned from the method.
So the PartDAO does not run any queries until the PartDAO is actually asked for some info. I used to have my PartDAO get its fields when it was created.But I decided it was better to have my DAOs as stateless.
I can see how this could be an issue. In fact my program uses 1 call per property of the DAO. For instance my pseudo business layer would have the Part class which would be setup by passing it a PartDAO. When it receives the PartDAO in its constructor it would do something like
name = dao.getName();
desc = dao.getDescription();
x = dao.getX();
etc...
So I have lots of queries to setup my environment. I may look at that for the future. Modification of my DAOs is pretty granular, but the creation can be in bulk. Actually the granular modification does not gain me much anyway since its hitting the network thats the cost not really the number of updated fields. Yea I will look at that. Hopefully I will find that my layer was constructed well enough that my pseudo business layer does not notice any changes I decide to make.
Thanks.
