Newbie - DAO problem.
Hi all,
I'm writing my first webapp using database connection pooling, and I'd like to use DAO design pattern also (I have never used it before).
The first problem is:
I have 2 db tables "users" and "roles", where every user can have more than one role. Now I create UserBean containing:
- userid as long
- username as String
- password as String
- roles as ArrayList
Then I create UsersDao, and there my problem begins.
When I add new user to my database, I have to add record to "users" and some records (with initial roles) to "roles". How to do this? Do I need to put all the code in addUser method, or maybe create separate method called "setRoles" or sth. If so, this method should be public (I mean, dao user has to call it) or private (method is called inside addUser method). The same with getRoles method when getting particular user from database.
Next thing - Exceptions in DAO:
I created my own class called DAOException, and everytime I catch SQLException I throw new DAOException. Is it right way of doing this?
And the last thing (for now):
I use connection pooling and DAO, I have BaseDAO class having two methods: getConnection (returns Connection from pool) and closeResources (closing connection, statement and resultset). Then every method in my UsersDAO class calls getConnection from parent class, uses this connection, and then closes all resources. Is this good? Or maybe I should create one connection for all methods (as a class field)?
Thanks for all replies
[1580 byte] By [
leezarda] at [2007-10-2 6:46:35]

> I'm writing my first webapp using database connection
> pooling, and I'd like to use DAO design pattern also
> (I have never used it before).
> The first problem is:
> I have 2 db tables "users" and "roles", where every
> user can have more than one role. Now I create
> UserBean containing:
> - userid as long
> - username as String
> - password as String
> - roles as ArrayList
Use the interface type for roles (e.g., Set or List). You can change the implementation easily that way. Since a User shouldn't have the same role appear twice, I'd say a Set type for roles is appropriate. Make HashSet the concrete type for fast access.
> Then I create UsersDao, and there my problem begins.
> When I add new user to my database, I have to add
> record to "users" and some records (with initial
> roles) to "roles". How to do this?
It's got to be INSERTs into each table, and they've got to be in the same transaction - if either one fails, both should roll back.
> Do I need to put
> all the code in addUser method, or maybe create
> separate method called "setRoles" or sth. If so, this
> method should be public (I mean, dao user has to call
> it) or private (method is called inside addUser
> method). The same with getRoles method when getting
> particular user from database.
You shouldn't be getting roles separately from the database. The idea is that once you get the User in the middle tier you'll use its data member to access roles.
> Next thing - Exceptions in DAO:
> I created my own class called DAOException, and
> everytime I catch SQLException I throw new
> DAOException. Is it right way of doing this?
Doesn't really add any new information, does it? (I'll bet you lose some, because you throw away the SQL error code and state that SQLException has.) The only advantage might be if you're making your DAOException a runtime rather than a checked exception.
Rod Johnson has a pretty extensive SQL exception hierarchy in his Spring framework. He adds a LOT of detail to his. I'd recommend that you emulate what he's doing.
> And the last thing (for now):
> I use connection pooling and DAO, I have BaseDAO
> class having two methods: getConnection (returns
> Connection from pool) and closeResources (closing
> connection, statement and resultset). Then every
> method in my UsersDAO class calls getConnection from
> parent class, uses this connection, and then closes
> all resources. Is this good? Or maybe I should create
> one connection for all methods (as a class field)?
I don't agree - I don't think the DAO should be responsible at all for acquiring or cleaning up Connections. What if you want several DAOs to participate in a transaction? That's up to a service layer that uses your DAOs.
Make the Connection something that's given to the DAO, and have the object that acquires it clean up as needed.
I also don't agree with a BaseDAO. I'd prefer that you start with an interface, like this:
public interface UserDao
{
public List findAll();
public User findById(Long id);
public void saveOrUpdate(User user);
public void delete(User user);
}
You can add other find methods if you need other WHERE clauses.
You should have a Dao interface for each top-level model object in your code. That means you'll have a UserDao, but not a RoleDao.
%
Hi,
First thing, DAOExceptions:
As far as I know, DAO's set of functions should be independent from data source, and throwing SQLException and catching it in layer using DAO makes my service layer dependent from data source, because I know it's kind of database and it throws SQLException. Then when I want to change my data storage to e.g. xml files or sth. it wouldn't throw SQLException. So it was the only reason why I made DAOException class.
Second - adding new user:
so you advise to put all the code in one method, without breaking it into addUser part and setRoles?
Third - DAO and BaseDAO:
again DAO should be an object getiing and setting data from/into database, and layer using it should know nothing about datasource and Connections. But then as you said it's impossible to use more than one dao in one transaction. Maybe I should use kind of DAOFactory having method to getting connection from pool, and passing this connection to particular DAO constructor. Then all my daos will use one connection. What do you think?
> Hi,
>
> First thing, DAOExceptions:
> As far as I know, DAO's set of functions should be
> independent from data source, and throwing
> SQLException and catching it in layer using DAO makes
> my service layer dependent from data source, because
> I know it's kind of database and it throws
> SQLException. Then when I want to change my data
> storage to e.g. xml files or sth. it wouldn't throw
> SQLException. So it was the only reason why I made
> DAOException class.
so how often do you plan to change data sources? How likely is it that you'll switch from SQL to XML? Not very, if this is more than a toy application. Any serious deployment will have its data in a SQL database, and those don't change very often.
> Second - adding new user:
> so you advise to put all the code in one method,
> without breaking it into addUser part and setRoles?
Right. You don't have a User without Roles, and Roles without their User make no sense on their own.
> Third - DAO and BaseDAO:
> again DAO should be an object getiing and setting
> data from/into database, and layer using it should
> know nothing about datasource and Connections.
No, you've misquoted me. The DAO does all the persistence work, so no other layer knows how it accomplishes that. But the service layer does know about the DAO, and it's the layer that knows about transactions, so that's the object that should be responsible for acquiring the necessary Connections to data sources.
> But
> then as you said it's impossible to use more than one
> dao in one transaction.
No, I don't believe I said that. (I'll check.) That's the point of passing a common Connection and its XA to all the DAOs that participate in that unit of work. I'm saying that your way of doing it, where each DAO gets its own Connection, makes it impossible for other DAOs to be part of that unit of work.
> Maybe I should use kind of
> DAOFactory having method to getting connection from
> pool, and passing this connection to particular DAO
> constructor. Then all my daos will use one
> connection. What do you think?
No again. You're getting carried away with factories here. You don't need more factory than java.lang.Class already gives you with its newInstance method. The key thing here is the interface:
public class FooJdbcDao implements FooDao
{
private Connection connection;
public FooJdbcDao(Connection connection)
{
this.connection = connection;
}
public void setConnection(Connection connection)
{
this.connection = connection;
}
// other methods here
}
public interface FooService
{
private FooDao fooDao;
public FooService(String fooDaoClassName)
{
// Here's your factory.
this.fooDao = Class.forName(fooDaoClassName).newInstance();
}
public List findAllFoos()
{
return this.fooDao.findAll();
}
}
}
%
> Hi,
>
> First thing, DAOExceptions:
> As far as I know, DAO's set of functions should be
> independent from data source, and throwing
> SQLException and catching it in layer using DAO makes
> my service layer dependent from data source, because
> I know it's kind of database and it throws
> SQLException. Then when I want to change my data
> storage to e.g. xml files or sth. it wouldn't throw
> SQLException. So it was the only reason why I made
> DAOException class.
>
How does DAOException truly insulate the service layer as opposed to SQLException? I can see one being a more generic case of the other. But regardless, the service layer must 'know' (and handle the cases where) the persistence tier throws an exception, be it checked or unchecked. If you want the service layer to be more agnostic to database failuers (and say handle them in a centralized application controller), then make the exceptions unchecked and handle all unchecked exceptions in a generic way in the application controller. "I'm sorry, an unexpected error has occurred with your request. Please try again later."
> Second - adding new user:
> so you advise to put all the code in one method,
> without breaking it into addUser part and setRoles?
>
This is an implementation decision. Break long methods into separate smaller methods. However, if the method in question is atomic, easy to understand and concise, then I do not see the need. Reuse is another consideration.
> Third - DAO and BaseDAO:
> again DAO should be an object getiing and setting
> data from/into database, and layer using it should
> know nothing about datasource and Connections. But
> then as you said it's impossible to use more than one
> dao in one transaction. Maybe I should use kind of
> DAOFactory having method to getting connection from
> pool, and passing this connection to particular DAO
> constructor. Then all my daos will use one
> connection. What do you think?
This is an idealized vision of a persistence strategy that is both rarely needed and rarely realized. The purpose of a persistence layer is to insulate your model and/or service layers from persistence code. However, the persistence classes *must* know something of the persistence mechanism used. How else will they achieve their purpose? You can implement layers of inheritance and abstraction to shield a caller from whether the resource in question is JDBC or some other persistence strategy, but you cannot shield callers from the fact that they are invoking persistence logic.
- Saish
Saisha at 2007-7-16 13:55:15 >

Saish's points are excellent, as always.%
> > Maybe I should use kind of
> > DAOFactory having method to getting connection
> from
> > pool, and passing this connection to particular
> DAO
> > constructor. Then all my daos will use one
> > connection. What do you think?
>
> No again. You're getting carried away with factories
> here. You don't need more factory than
> java.lang.Class already gives you with its
> newInstance method. The key thing here is the
> interface:
>
> > public class FooJdbcDao implements FooDao
> {
>private Connection connection;
>
>public FooJdbcDao(Connection connection)
>{
> this.connection = connection;
>}
>
>public void setConnection(Connection connection)
>{
> this.connection = connection;
>}
>
>// other methods here
> }
>
> public interface FooService
> {
>private FooDao fooDao;
>
>public FooService(String fooDaoClassName)
>{
> // Here's your factory.
> this.fooDao =
> fooDao =
> Class.forName(fooDaoClassName).newInstance();
>}
>
>public List findAllFoos()
>{
> return this.fooDao.findAll();
>}
> }
>
> }
>
>
> %
Having designed and developed a Generic Data Access Layer lately using a factory mechanism, I must say I don't see the point in adding this kind of additional indirection... What's more, your FooService doesn't really encapsulate dao creation (since it seems agnostic of the underlying implementation). Binding between service and its implementation has to lie elsewhere anyway, doesn't it ?
I'd rather have a generic :
public interface DAOFactory {
public <T extends DAO> T createDAO(Class<T> daoType);
}
which can be overridden for each concrete DAO implementation class (class meaning here "SQL", "Web Service" or whatever) and that's configured (meaning binding daoType (Foo) <=> daoClass (JdbcFoo) made) by (ideally) the framework, or (at "worst") by a custom singleton factory).
I realise I'm being very unclear, and I won't be able to continue this discussion until this evening (European time), but I'm highly interested :)
> Having designed and developed a Generic Data Access
> Layer lately using a factory mechanism, I must say I
> don't see the point in adding this kind of additional
> indirection...
Not sure what you mean, but I'm willing to learn.
Your generic DAO layer depends on JDK 1.5, of course. Not everyone is there yet. If you're using WebLogic 8.1, for instance, you don't have a choice.
> What's more, your FooService doesn't
> really encapsulate dao creation (since it seems
> agnostic of the underlying implementation).
Of course - that's what interfaces are. "Agnostic of underlying implementation" - sounds like a fine definition. Now if I want to implement in terms of relational databases using Hibernate, JDBC, JDO, or iBatis, clients don't have to care.
> Binding
> between service and its implementation has to lie
> elsewhere anyway, doesn't it ?
Yes, in an inversion of control/dependency injection framework like Spring, PicoContainer, WebWork, etc.
> I'd rather have a generic :
> > public interface DAOFactory {
> public <T extends DAO> T createDAO(Class<T>
> s<T> daoType);
> }
>
Not me. I think IoC will take me further.
> which can be overridden for each concrete DAO
> implementation class (class meaning here "SQL", "Web
> Service" or whatever) and that's configured (meaning
> binding daoType (Foo) <=> daoClass (JdbcFoo) made) by
> (ideally) the framework, or (at "worst") by a custom
> singleton factory).
Only if you're using JDK 1.5 and don't have an IoC framework to help you.
I think a Spring-based DAO is a better choice.
%
Generic DAO like this? http://hibernate.bluemars.net/328.html%
> > Having designed and developed a Generic Data
> Access
> > Layer lately using a factory mechanism, I must say
> I
> > don't see the point in adding this kind of
> additional
> > indirection...
>
> Not sure what you mean, but I'm willing to learn.
>
> Your generic DAO layer depends on JDK 1.5, of course.
> Not everyone is there yet. If you're using WebLogic
> c 8.1, for instance, you don't have a choice.
>
>
> > What's more, your FooService doesn't
> > really encapsulate dao creation (since it seems
> > agnostic of the underlying implementation).
>
> Of course - that's what interfaces are. "Agnostic of
> underlying implementation" - sounds like a fine
> definition. Now if I want to implement in terms of
> relational databases using Hibernate, JDBC, JDO, or
> iBatis, clients don't have to care.
>
> > Binding
> > between service and its implementation has to lie
> > elsewhere anyway, doesn't it ?
>
> Yes, in an inversion of control/dependency injection
> framework like Spring, PicoContainer, WebWork, etc.
>
> > I'd rather have a generic :
> > > > public interface DAOFactory {
> > public <T extends DAO> T createDAO(Class<T>
> > s<T> daoType);
> > }
> >
>
> Not me. I think IoC will take me further.
>
> > which can be overridden for each concrete DAO
> > implementation class (class meaning here "SQL",
> "Web
> > Service" or whatever) and that's configured
> (meaning
> > binding daoType (Foo) <=> daoClass (JdbcFoo) made)
> by
> > (ideally) the framework, or (at "worst") by a
> custom
> > singleton factory).
>
> Only if you're using JDK 1.5 and don't have an IoC
> framework to help you.
>
> I think a Spring-based DAO is a better choice.
>
> %
right, I see we're on the same wavelength there then... Unfortunately, I couldn't push Spring through to the decision makers by the time I really came to think about it, but basically we're doing the same thing with different tools... :)
> Generic DAO like this?
>
> http://hibernate.bluemars.net/328.html
>
> %
kind of
except that I had to write a JDBC code generator instead of using Hibernate and its associated generator tools (having to deal with an outdated DBMS that seems to be incompatible with Hibernate)
the result is quite elegant, efficient and perfectly OO, as far as I can tell, but of course far more monolithic than reusing an existing wonder like Hibernate ;-)
anyway, Hibernate could very well be plugged instead of my generated JDBC layer some day... that's the kind of thing I constantly kept in mind while designing it
> anyway, Hibernate could very well be plugged instead
> of my generated JDBC layer some day... that's the
> kind of thing I constantly kept in mind while
> designing it
Right, Torajirou, if you've kept to an interface you can always switch to a Hibernate implementation (or JDO or iBatis) if your elegant JDBC solution doesn't suit you anymore.
We're on the same page.
%
PS - I hope it's the same book. 8)