-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 21 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: DAO and findById()
PostPosted: Wed Mar 14, 2007 12:00 pm 
Beginner
Beginner

Joined: Wed Mar 14, 2007 10:19 am
Posts: 24
I have some questions about DAO.

I have a simple application that uses Hibernate 3.1, jsf, Tomcat and hsqldb.
I want to use DAO classes for every pojo. Should I use findById() and findAll()?Is it obligatory?And if yes is something like the following correct?

Code:
public User findById(Long id) throws HibernateException {
log.debug("findById()");
session = HibernateUtil.getSessionFactory().getCurrentSession();
User user = session.load(this.daoClass,  id);
session.flush();
session.close();
        return user;
}



The other I want to ask is what about the Transactions. In my methods in the DAO I use the following:
Code:
Context ctx = new InitialContext();
tx = (UserTransaction)ctx.lookup("java:comp/env/UserTransaction");
...
tx.commit();


Should I use the above in the findById() and in the findAll() also?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 14, 2007 1:08 pm 
Expert
Expert

Joined: Fri Aug 19, 2005 2:11 pm
Posts: 628
Location: Cincinnati
you could just do tx = session.beginTransaction() and use Hibernate's transaction, which will use the same connection that you have hibernate configured to use.

and those methods aren't obligatory, just convenience methods that do basic loading.

_________________
Chris

If you were at work doing this voluntarily, imagine what you'd want to see to answer a question.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 15, 2007 4:47 am 
Beginner
Beginner

Joined: Wed Mar 14, 2007 10:19 am
Posts: 24
First of all thank you for you answer:

kochcp wrote:
you could just do tx = session.beginTransaction() and use Hibernate's transaction, which will use the same connection that you have hibernate configured to use.


I prefer to use a JTA transaction and not Hibernate transaction.

Is it better to pass Session from the service layer (EJB or something more light) as a parameter like that:

Code:
public class UserDao() {

public AbstractDAO(Session session) {
    this.session = session;
}

  public User findById() {
  User user =  session.load(this.class, id);
  return user;
  }

}


or to open session in the dao level like that:

Code:
public User findById() {
  Session session = HibernateUtil.getCurrentSession() ;
  User user =  session.load(this.class, id);
  session.flush();
  session.close();
  return user;
  }


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 15, 2007 5:27 am 
Expert
Expert

Joined: Thu Sep 04, 2003 8:23 am
Posts: 368
If you don't want your code to be mess by session open / close think using a declarative transaction layer like ejb container or spring.
I am using spring with hibernate and it works like a charm. You don't have to take care on session open/close
With your solution what would you do when you will have inter dao calls ? How do you know at the end of the method if you have to close the session or not ?
With Spring handling transaction propagation you won't have this kind of problems

_________________
Seb
(Please don't forget to give credits if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 15, 2007 5:50 am 
Beginner
Beginner

Joined: Wed Mar 14, 2007 10:19 am
Posts: 24
Unfortunately I cannot use Spring, or Ejbs due to the specifications of the project.If I use the first solution

Code:
public class UserDao() {

public UserDAO(Session session) {
    this.session = session;
}

  public User findById(Long id) {
  User user =  session.load(this.class, id);
  return user;
  }

}


won't I be ok? I will open the session in the service layer lets say in a method getUser() and if I want to call findById() I will do sth like that:

Code:
public User getUser(Long id) {
Session session = HibernateUtil.getCurrentSession();
UserDAO userDao = new UserDAO(session);
userDao.findById(id);
session.flush();
session.close();
}



Is this a bad solution?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 15, 2007 5:54 am 
Expert
Expert

Joined: Thu Sep 04, 2003 8:23 am
Posts: 368
This is not a bad solution but transaction demarcation is a complex thing.
I don't how big is your application but in the future you may have some problems.
You open and close the session in the getUser method in your service layer. But what will you do in the future if this method is called both from the gui and from another service method that open the session. You will have to deal with this in a case by case basis.
Declarative transactions frameworks are really useful in complex projects, so bad you can't use them

_________________
Seb
(Please don't forget to give credits if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 15, 2007 6:40 am 
Beginner
Beginner

Joined: Wed Mar 14, 2007 10:19 am
Posts: 24
1)Is it better to open the Session in the Service Layer or in the DAO?

Quote:
But what will you do in the future if this method is called both from the gui and from another service method that open the session. You will have to deal with this in a case by case basis.


2) Since I am using getCurrentSession() if another method in the session bean calls method getUser() then if an existing session exists in the 1st method the current session will be used so where is the problem?

3)Since I am not using Ejbs and I am using Tomcat am I not obliged to open and close Transactions on my own?And where is the proper layer to do that?
So my project is organized as : JSF--> managed bean --> service layer --> DAOs(I do not know yet what I will use in the service layer.)
The transactions should open in the managed bean or in the service layer?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 15, 2007 6:55 am 
Expert
Expert

Joined: Thu Sep 04, 2003 8:23 am
Posts: 368
Session management is better to put in the service layer

With currentSession you don't have any problems for session opening but what about closing ? How do you know when you have to close the session ?

_________________
Seb
(Please don't forget to give credits if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 15, 2007 7:18 am 
Beginner
Beginner

Joined: Wed Mar 14, 2007 10:19 am
Posts: 24
scesbron wrote:

With currentSession you don't have any problems for session opening but what about closing ? How do you know when you have to close the session ?


Every session will open and close in every method of the service layer.

What about the transactions?I should open then in the service layer or in the managed beans?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 15, 2007 9:05 am 
Expert
Expert

Joined: Thu Sep 04, 2003 8:23 am
Posts: 368
If you don't use long session (that span accross multiple client calls) just think about one session = one transaction. They are the same unit of work. Begin the transaction when you open the session and commit or rollback the transaction when you close the session

Just an example :
Code:
public void methodA() {
  Session session = HibernateUtil.getCurrentSession();
  // Do something
  methodB();
  // Do something else
  session.flush();
  session.close();
}
public void methodB() {
  Session session = HibernateUtil.getCurrentSession();
  // Do something
  session.flush();
  session.close();
}

What do you think about session state at the end of methodA : do you think everything will de find when we arrive at "do something else" ?
Session and transaction management is not a simple thing : that's why there is some frameworks that handle them for us

_________________
Seb
(Please don't forget to give credits if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 16, 2007 8:06 am 
Beginner
Beginner

Joined: Wed Mar 14, 2007 10:19 am
Posts: 24
scesbron wrote:
Session and transaction management is not a simple thing : that's why there is some frameworks that handle them for us


I would prefer to have a jboss application server and EJBs and let them handle the transaction management, but the specs of my project need Tomcat!

So I saw your example, but I didn't get your point. You suggest to open session and open transaction in each method of the service layer?and close them in the end of the method respectively?You are implying that this will cause a problem?

Moreover is session.flush() necessary or it is done when I commit the transaction?


Thank you...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 16, 2007 9:18 am 
Expert
Expert

Joined: Thu Sep 04, 2003 8:23 am
Posts: 368
Yes flush is called by default when you commit a transaction.

I just want to show in my example that after methodA has called methodB, as methodB closed the session, it is not possible to use it anymore in methodA. So if methodB is called directly and through methodA you will have a problem. The other solution is to create a methodC that is called both by methodA and methodB and that does not take care of session closing but time after time, when your application grow theses problems are more and more complex

_________________
Seb
(Please don't forget to give credits if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 16, 2007 9:26 am 
Beginner
Beginner

Joined: Wed Mar 14, 2007 10:19 am
Posts: 24
Ok I understand what you are saying but I disagree, in that methodB will close the session that opens in methodB, the session that is open from methodA will still be open.

methodA

session from method A

methodB
open session in method B
close session in method B
end of methodB

close session in methodA

end of methodA



Am I correct?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 16, 2007 9:34 am 
Expert
Expert

Joined: Thu Sep 04, 2003 8:23 am
Posts: 368
The whole point here is to share a session between several methods because a Session is a unit-of-work in hibernate and some stuff like lazy loading does not work outside the session that loads the object.
The main goal of HibernateUtil.currentSession is to reuse an already opened session.
In my point of view, getCurrentSession in methodB will return the same session as the one opened in methodA and the close method will close this unique session.

_________________
Seb
(Please don't forget to give credits if you found this answer useful :)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 16, 2007 10:00 am 
Beginner
Beginner

Joined: Wed Mar 14, 2007 10:19 am
Posts: 24
Ok I understand your opinion. If I used sessionFactory.openSession() it would be ok then to close it in every method.

Lets say I am using sessionFactory.getCurrentSession() in every method.
When it is the right time to close it and where?

And I have the same question for the transaction..
If I have session.beginTransaction() where should I open it and where should I close it?In every method?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.