views:

51

answers:

1

Hi all, 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.

+2  A: 
  1. You are handling the transaction inside your actionPerformed() method. Its clearly defeating the purpose of DAO/Service layer
  2. 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.

  1. You can look into GenericDAO concept for this. That might suit your need
  2. 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
  3. 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.

Adeel Ansari
@Adeel Ansari: 1- where can i handle transaction? 2- why this is not correct? Specific data operation is into service layer.
blow
@blow: You can handle that in your DAO or Business method. I usually prefer to do it in my business method.
Adeel Ansari
@Adeel Ansari: now my genericDao is like this http://community.jboss.org/wiki/GenericDataAccessObjects but i have not implemented DaoFactory.Can you write a simple example to show me how and where handle session and transaction? I think do not understand what business-logic means.
blow
@blow: Oh okay. Now as you are keeping your DAO, then its fine to manage transaction in DAO methods. Perhaps, the only problem you will encounter when in your calling code you need to load some associations which is configured as `fetch-lazy`. Why because your session is already closed and you can make a trip to database.
Adeel Ansari
@blow: And my business method I simply mean the method which suppose to perform some business logic and it needs data in order to perform that. That method can also handle transaction, because that method is more aware about what is needed, IMO. Hence, having a right to manage transaction. In this way, you can ask for as much data as required to perform that particular business function, without closing the session. I hope this will make things clear.
Adeel Ansari
@Adeel Ansari: But i do not manage transaction in my DAO, transaction are handled external to DAO, for this reason im not sure if is correct where i handle my transaction... into DAO im only use a session, but "session.beginTransaction" and "trasnaction.commit" are not inside it.
blow
+1 to get closer to 10k :)
willcodejavaforfood
@blow: And how you get session in your DAO? BTW, you are asking for session in your `actionPerformed()` too. Do you not think you are asking for the session twice?
Adeel Ansari
@Adeel Ansari: in my DAO i simple obtain session in this way: HibernateUtil.getSessionFactory().getCurrentSession(), but never begin a transaction or commit it.Yes, it is obtain twice, but it is managed by Hibernate, so current session is the same session.ps: i've edited my question, is my example a business metheod? Thanks again.
blow
@blow: Yes, its likely going to be the same session. But it doesn't look very neat. Now 2nd question, yes, it can be said a business method, precisely.
Adeel Ansari
@Adeel Ansari: ok, thank you again!
blow