I need an advice w.r.t. one of the design approach we are considering.
We are implementing a Java web service provider which acts on data in relational database. Our propose classes are:
IDAO - interface with execute() method
GetCustomerDAO and UpdateCustomerDAO implements IDAO
DAOFactory - List of DAO to be reads configuration file which has a mapping of DAOs to be invoked for a particular service.
ServiceImpl - contains getCustomer, updateCustomer methods. The service uses DAOFactory to get list of DAO objects and it then iterates over the list and calls DAO.execute method.
I think it's more of like we have converted DAOs in to Command. However, I don't quite like this approach for some reasons:
- In ServiceImpl : you can't influence the flow of DAOs being called. For e.g. after execution of 1st DAO if I don't want to execute 2nd DAO but execute 3rd DAO, it's hard to have this implemented.
- besides not sure if we can conceptually use DAO. because a Command object can have business logic, however DAOs should only deal with aspects of reading and writing data to db.
Please let me know your views whether the design looks appropriate. thanks
I don't see the benefit of using the Command design pattern in this case.
1. The idea with DAO, is to provide an interface that abstract a persistence mechanism. This interface traditionally defines CRUD methods. Each DAO concrete class, would typically implement the DAO interface, for a specific persistence mechanism.For instance, you could have one implementation that stores data into a relational database and another that stores data into an xml file. Both these implementation can be interchangeable since they implement the same inteface.
2. The service functionality can be separated into a separate service layer. Normally, this layer has a dependency on your DAO layer(for persistence). The service interface can be similar to a façade that exposes the business logic implemented in the application (typically, logic in the business layer) to potential clients. Example:
User DAO interface:
public interface UserDao {
void save(User user);
void delete(User user);
void update(User user);
User findByUsername(String username);
List findAll();
...
}
User Service interface:
public interface UserService {
void createUser(String username, String password);
boolean loginUser(String username, String password);
boolean isUsernameUnique(String username);
....
}
Service implementation:
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl(UserDao userDao){
this.userDao = userDao;
}
...
}
Related
What is the difference between using #Transactional in dao layer and in service layer?
#Transactional
class UserDAO{}
or
#Transactional
class UserService{}
We can put this annotation in both the layers. So what is the difference?
if you add #Transactional annotation at Service layer and you are performing multiple operations on database, then all these operations will be in a single transaction and with that you can make sure that both the operations are commited, if any of them failed then roll back.
For example: There is a case you want to create an Employee and your business rule says that for every Employee you create, you need to create User in your database. In such case we would use Transactional annotation at service layer
#Service
public class EmployeeService {
....
#Transactional
public int createEmployee(Employee emp) {
//create Employee
employeeDao.createEmployee(emp);
User user = new User();
// some fileds of employee are used to create a User
user.setEmployeeId(emp.getEmployeeId());
....
userDao.createUser(user);
...
}
}
There is no difference at all. But best practice is use it in Service layer. Cause sometimes you need to make transaction through more than one entity. So if you declare transactions in your dao manually. And you call method from service with two methods from your daos you will have two transactions in one call. And that is something what you don't want.
I have a #SessionScoped ApplicationBean for storing user login info and injecting it into other managed beans successfully as told here.
I also use my Dao interfaces by #ManagedProperty annotation but I feel something wrong with my usage.
Assume that there is as StockDao that has a public method listStocks(String companyCode) and companyCode is stored in the ApplicationBean when user logins.
So my managed bean is calling the DAO layer like this
#ManagedProperty(value = "#{appBean}")
ApplicationBean appBean;
public void getStockList() {
return stockDao.listStocks(appBean.getCompanyCode());
}
This repeats everywhere where the sql needs companyCode.
I feel that it would be better if my DAO layer had known companyCode (which means injecting ApplicationBean into DAOs) and I should use my methods like below
public void getStockList() {
return stockDao.listStocks();
}
So the question is, which API design would be better and if you vote for the second, how can I inject #SessionScoped beans into DAO layer?
For me 1st approach is much cleaner ,
i dont want to tie DAO layer with the session managed bean.
I keep my general artifacts especially daos and data models packaged as a seperate Jar , without any external dependencies
This way i could use the same without any modifications be it a Web App , Stand Alone or in an EJB
This keeps your Dao independent of how/where the Company Code is fetched from
You do not use session variables in the DAO layer. Lack of business logic and user interface matters is exactly what makes it DAO: a layer responsible just for abstracting data access.
If you add session-dependent state, you will turn your DAO layer into DAAMUIS layer (the ubiquitous Data Access And Miscellaneous User Interface Stuff layer). I am not saying that DAAMUIS is wrong or evil, just that the question needs rephrasing.
I have a GenericDAO which delegates its operations to a DataSource class
public class BaseDAOImpl<T> implements BaseDAO<T> {
DataSource ds;
public T update(T entity) {
ds.update(entity);
}
The issue I'm having right now is that we want it to work with multiple DataSources. This leaves me with 2 alternatives
1) make a setter in DAO for datasource and use it before every operation
2) create each child of BaseDAO n times per number of datasources
I would like DataSource to get out of DAO, but then how the actions can get delegated to it?
I guess you want to implement something like multitenancy: when request comes from the user A, all DAO involved into processing that request should talk to user A's DataSource, and so on.
If so, DataSource is a part of context for your request, and one possible option to store this kind of contextual data is to use ThreadLocal:
When request comes, you put the appropriate DataSource into ThreadLocal
All DAOs obtain the DataSource from that ThreadLocal.
Obviously, for the sake of Single Responsibility Principle it would be better to hide this logic behind a factory and inject that factory into your DAOs, so that DAOs will call factory.getCurrentDataSource() for each operation.
Clear ThreadLocal when you finished processing of the request.
Note that it only works if each request is processed by a single thread.
You can use a factory for creating your datasource, so depending on your requirement create your datasource and then if you can use dependency injection to have your datasource injected to your DAO.
To get rid of datasource in DAO you can use Delegate Pattern, inject delegator in your DAO, your delegate will have reference of DataSource.
Also to note if you persist with just one generic DAO, your DAO may eventually get blotted with methods which are not generic but more specific to a certain functionality of your application, IMHO you should also consider breaking your DAO to more specific level leaving the generic DAO actually do the generic work.
I wouldn't use a setter for the data source, I would pass it in the constructor for the DAO. Doesn't seem right to be able to change the data source during the life of the DAO object.
Well I think, you should try and use dependency injection in this case. Your base class would be abstracted from type of datasource. So even if you are adding a new type of datasource the only change that you would end up doing would be the factory method which would generate a type of DataSource object based upon current request and hence increase loose coupling of your application
interface IDataSource<T>
{
T update<T>(T entity);
}
public ConcereteDataSource<T> : IDataSource<T>
{
public T update<T>(T entity)
{
//Concerete implementation
}
}
public class BaseDAOImpl<T> implements BaseDAO<T>
{
public IDataSource ds {get;set;}
public T update(T entity) {
ds.update(entity);
}
//where you try to instansiate a new instance of Base DAO
//Factory to create a new instance of datasource for this context
IDataSource contextualDs = GetDataSourceForThisUser();
BaseDAOImpl<SomeType> dao = new BaseDAOImpl<SomeType>();
//inject the dependency
dao.ds = contextualDs;
im in trouble with implemenetation of a service layer, i think i did not understand this concept very well.
In a DAO implementation i can write all CRUD logic for a specific technology and entity (for example hibernate and User table), and in a service layer we use a DAO for all data operation for the entity in DAO (like getUser, loginUser, etc..) is this ok?
If this is ok i have a simple question, can i handle database connection (or in case of hibernate, session and transaction) within service layer, DAO implementation or neither?
Example, i have a simple GUI with one Button(load all User), and a table will contains all User. Pressing the Button will load the table with all users.
I have a HibernateDAO for User entity (UserHibernateDAO) containing all CRUD operation and a service layer, UserService, for some specific data operation with user.
ServiceLayer:
public class UserService extends AbstractServiceLayer{
private AbstractDAO dao;
public UserService(AbstractDAO dao){
this.dao=dao;
}
public List<User> loadAllUsers(){
return dao.findAll();
}
}
In actionperformed of Button:
private void buttonActionPerformed(ActionEvent evt) {
Transaction transaction=HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List<User> users=userService.loadAllUsers();
loadTableWithUsers(users);
transaction.commit();
}
Is this implementation ok?
Session and transaction handle is in the right position or i have to put it into service layer? ..or perhaps into dao?
EDIT1:
If i have an interface UserDAO and a UserHibernateDAO that implements UserDAO, service layer has no reason to exists, isn't true?
Becouse i can have all method to manage an "USER" inside my UserDAO and UserHibernateDAO implements all this methods for hibernate technology... then i could have a UserJdbcDAO, UserMysqlDAO etc... mmm...
EDIT2:
private void buttonActionPerformed(ActionEvent evt) {
myBusinessMethod();
}
private void myBusinessMethod(){
Transaction transaction=HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List<User> users=userService.loadAllUsers();
loadTableWithUsers(users);
//some other useful operation before close session
transaction.commit();
}
im not sure, a business method is a method like this?
Thanks all.
You are handling the transaction inside your actionPerformed() method. Its clearly defeating the purpose of DAO/Service layer
Your UserService is accepting AbstractDAO, which means some other code may pass wrong DAO implementation to your UserService that will screw things up
Now, few suggestions.
You can look into GenericDAO concept for this. That might suit your need
Most of the time we ain't need all these layers like Service, DAO and BusinessDelegate. So, question yourself are any of these really answering some of your questions. If not, get rid of them. YAGNI
Get rid of DAO completely, and treat your Hibernate API as your DAO. Handle database transaction in your business methods. You may like to read this question
[Edited]
After your edit my 3rd suggestion doesn't carry much weight. By the way, you name your DAOs as follows; UserJdbcDAO, UserMysqlDAO etc. Your 2nd name is not making much sense, as we use ORMs just to avoid DB vendor specific DAOs/queries. It might start making some sense if your UserMysqlDAO extends UserJdbcDAO.
I've been reading about the sun blueprint GenericDAO implementation and Gavin King's take on this for use with Hibernate. It seems he doesn't mention anything about transaction handling:
public abstract class GenericHibernateDAO<T, ID extends Serializable> {
protected Session getSession() {
return HibernateUtil.getSessionFactory().getCurrentSession();
}
public T makePersistent(T entity) {
getSession().saveOrUpdate(entity);
return entity;
}
}
I'm puzzled as to where I should put the start/end of the transaction. Currently they are inside the DAOs that extend this GenericHibernateDAO
public class FooHibernateDAO extends GenericHibernateDAO<Foo, Long> {
public Foo saveFoo(Foo foo) {
getSession().beginTransaction();
makePersistent(foo);
getSession().getTransaction().commit();
}
}
Should the transaction handling be managed by the caller of the DAO in the application tier?
Generally the best practice is to manage transactions in service layer not in DAO layer. Each DAO method generally handles one specific operation and a service method aggregates them in one transaction.
Transactions should be managed in the application tier. Say for example you had an AccountDAO:
public class AccountDAO {
public void DebitAccount( int accountId, int dollars ) {
}
public void CreditAccount( int accountId, int dollars ) {
}
}
If I wanted to transfer money between accounts, I would call DebitAccount on one account and CreditAccount on another. I would want these calls to happen in the same transaction. The DAO can't possibly know that, but the application tier would.
If transactions were managed at the DAO tier, you would need to create another TransferMoney method on the DAO to do it in one transaction. This would eventually bloat your DAO tier and, for complex operations, bring in business logic that probably shouldn't be there. And it gets even messier if you have an operation that requires multiple DAOs to be involved in a single transaction.