-->
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.  [ 12 posts ] 
Author Message
 Post subject: lazy collections and open session in view once again
PostPosted: Tue Nov 25, 2003 7:45 am 
Newbie

Joined: Tue Nov 25, 2003 7:33 am
Posts: 4
Hi!

I'v searched docs and forum archives and still confused on how correctly to process sessions in view... Let's say I have a service manager, which returns DTO, smth. like MenuItem item = (MenuItem)ServMan.findByPrimaryKey(MenuItem.class, 1) then I pass MenuItem DTO to servlet context and use it there. The only problem is that MenuItem is mapped with lazy children collection, and when (in View) i need to iterate it, i get Exception, of course, since session is disconnected (sevicemanager closes session after it finds DTO). The only object I have in view is DTO...

After reading all this stuff (ThreadLocalSession, opensessioninview etc.) I still have no idea how to solve this problem, I am sorry I am a lobotomized flatworm, but I need help.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 25, 2003 9:27 am 
Newbie

Joined: Tue Nov 25, 2003 7:33 am
Posts: 4
well, I am sure you all answered this question for zillion times, but I just did not found the answer. Hibernate-Tomcat guide while being pretty simple and straitforward, stops on the most interesting part, the question is not how to map collеctions and classes, it is covered well in documentation, but how to deal with lazy collections form tomcat-hibernate in a simple manner...


Top
 Profile  
 
 Post subject: session.filter()
PostPosted: Tue Nov 25, 2003 9:58 am 
Regular
Regular

Joined: Sun Sep 21, 2003 11:43 pm
Posts: 85
Location: Massachusetts
Sounds like you need a Session.filter() call. From the javadocs (on the web site):

Apply a filter to a persistent collection. A filter is a Hibernate query that may refer to this, the collection element. Filters allow efficient access to very large lazy collections. (Executing the filter does not initialize the collection.)

Regards,
David


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 25, 2003 10:09 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
What puzzled you in http://www.hibernate.org/Documentation/ThreadLocalSession ?

Usage is then
Code:
Session s = HibernateSession.currentSession(); //open session
MenuItem item = (MenuItem)ServMan.findByPrimaryKey(MenuItem.class, 1);
Set result = item.getCollection();
...
HibernateSession.closeSession();
// avoid try catch to simplify


In findByPrimaryKey()
Code:
Session s = HibernateSession.currentSession(); //get current session
return s.load(MenuItem.class, New Integer(1));
// no session close

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 26, 2003 5:45 pm 
Newbie

Joined: Tue Nov 25, 2003 7:33 am
Posts: 4
epbernard, once again please, for lobotomized etc.

1. in ServiceManager
a) get session from ThreadLocal
b) return DTO
c) DO NOT CLOSE ThreadLocal session

2. in view, let's say blah.jsp
a) get session from ThreadLocal
b) get DTO from ServiceManager.getDTO()
c) do what I need with DTO collections etc.
d) CLOSE ThreadLocal session

is that all right?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 26, 2003 6:18 pm 
Regular
Regular

Joined: Tue Sep 02, 2003 5:09 pm
Posts: 81
Location: Whitefish Montana
You might try to disconnect the session at 1c and add 2a+ that reconnects. That way if something goes wrong between step 1 and 2 you won't leave your connection hanging open.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 26, 2003 6:32 pm 
Senior
Senior

Joined: Sun Aug 31, 2003 3:14 pm
Posts: 151
Location: Earth (at the moment)
Quote:
1. in ServiceManager
a) get session from ThreadLocal
b) return DTO
c) DO NOT CLOSE ThreadLocal session

2. in view, let's say blah.jsp
a) get session from ThreadLocal
b) get DTO from ServiceManager.getDTO()
c) do what I need with DTO collections etc.
d) CLOSE ThreadLocal session

is that all right?


Essentially, "Yes", that is correct.
To perhaps clarify if need be...
If you use a ServletFilter as outlined on the wiki in the open session in view stuff you do not need to manually open and close the session, the filter will do that for you. Your container will run the filter before handing control over to your servlet(s) and the filter will finish running and automatically close the session after the view is finished being generated and control has passed out of whatever servlet(s) the filter is applied to. Then in your code you can simply request the session from the filter in your ServiceManager (or pass it in) and forget about it. What you outlined in steps 2b - 2c will work just fine because the DTO will still be associated with the unclosed session and can therefor lazily initialize. You should not step 2d manually as the filter will do that automatically.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 26, 2003 7:10 pm 
Newbie

Joined: Tue Nov 25, 2003 7:33 am
Posts: 4
to dmmorris: okay, so this could be something like this:

1c) (that is service manager)
blah-blah;
session.disconnect(); //that will disconnect ThreadLocal session from its connection, yep?

2a) get session from ThreadLocal and do session.reconnect()

when doing things this way we can be sure that nothing left unclosed, that is what for clever people use this?

to DavidNDuffy: Well, it looks like the most easy and smooth solution, but one thing is confusing me: in the comments to that nice document about OpenSessioninView we can see that someone argues that since it will open one session per request (that is per thread in the case of web, yes?) and leave it unclosed untill the end of rendering, the quantity of simultaneosly rendered requests will be limited by connection pool capabilities (something like MaxActive in DPCB)... After lobotomization I can not be sure, that any solution based on ThreadLocal (either via Filter, or manually, like this way) will not suffer the same, so, If you promise that that is okay to use Filter, I'll better use the Filter solution...

Also (in the case of using Filter to do this job) it is not clear for me (sorry, but I've told about lobot...) how it would be better to deal with closing connections etc (again), okay, if ServiceManager will recieve sessions from ServletFilter, it (ServiceManager) should NOT close sessions, is that right? And, in the case of using ServiceManager from outside web context at all, it should be provided with manually opened and closed session?

Thank you.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 26, 2003 7:18 pm 
Regular
Regular

Joined: Tue Sep 02, 2003 5:09 pm
Posts: 81
Location: Whitefish Montana
DavidNDuffy wrote:
Quote:
1. in ServiceManager
Your container will run the filter before handing control over to your servlet(s) and the filter will finish running and automatically close the session after the view is finished being generated and control has passed out of whatever servlet(s) the filter is applied to.


My experience with Struts (with tiles) is that there are several requests generated and I had to look at the request URI like this:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chn)
throws IOException, ServletException {
String requestedResource = ((HttpServletRequest) req).getRequestURI();
boolean do = requestedResource.endsWith(".do");
boolean jsp = requestedResource.endsWith(".jsp");
...

I opened/disconnected on the .do and reconnect/close on a .jsp.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 26, 2003 7:27 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
moedusa wrote:
Also (in the case of using Filter to do this job) it is not clear for me (sorry, but I've told about lobot...) how it would be better to deal with closing connections etc (again), okay, if ServiceManager will recieve sessions from ServletFilter, it (ServiceManager) should NOT close sessions, is that right? And, in the case of using ServiceManager from outside web context at all, it should be provided with manually opened and closed session?

Thank you.

Your ServiceManager will never ever close session. It is done by the caller of ServiceManager.

_________________
Emmanuel


Top
 Profile  
 
 Post subject: more...
PostPosted: Thu Nov 27, 2003 1:46 am 
Senior
Senior

Joined: Sun Aug 31, 2003 3:14 pm
Posts: 151
Location: Earth (at the moment)
Personally I would think that if you close your thread local session in the ServiceManager and then have to reconnect it you've more or less defeated the purpose of storing an "open" session. If something were to go wrong and for some reason the session didn't get closed Hibernate would still detect it and clean up after you and issue a warning so the connections would not be left hanging indefinitely.

to dmmorris:
Have you mapped the filter to run on more than just the ActionServlet?
I'm using Struts and I don't have to do any fancy checking of request extension. The filter runs and opens a session whenever a request is made to the Struts ActionServlet (i.e. every Struts request) and finishes and closes the session after the view has been rendered and control passes out of the ActionServlet. All of the jsp rendering et. al. is covered by this because the ActionServlet hasn't actually finished until the view is constructed.
pseudo:
Code:
- filter starts (opens session)
  - ActionServlet starts
    - view is rendered
  - ActionServlet finishes
- filter finishes (closes session)


to moedusa:
Quote:
...the quantity of simultaneosly rendered requests will be limited by connection pool capabilities...

That could very well be true but unless you get a very large volume of concurrent requests so close together that they can't finish executing fast enough to free up connections that wouldn't be a problem.
Quote:
...if ServiceManager will recieve sessions from ServletFilter, it (ServiceManager) should NOT close sessions, is that right?

That is correct, it should NOT close the sessions.
Quote:
in the case of using ServiceManager from outside web context at all, it should be provided with manually opened and closed session?

Also correct, that is why it is good to have your ServiceManager be passed an open session as a parameter rather than ask for one explicitly from somewhere (this way you can use the filter to get a session when running in your web container and you can use another approach for your unit tests and still use the same ServiceManager etc. for both scenarios).


Top
 Profile  
 
 Post subject: Re: more...
PostPosted: Thu Nov 27, 2003 4:50 pm 
Regular
Regular

Joined: Tue Sep 02, 2003 5:09 pm
Posts: 81
Location: Whitefish Montana
You are right. I looked at the code more closely and the only time you need to disconnect with pure Struts applications is when you redirect to another action and you have a Class maintaining state for the application.

In realitiy, I don't actually create a Hibernate session in the Filter. I just create a ThreadLocal session manager if one doesn't exist. If one does exist it closes any open sessions. I only create a Hibernate session when a service asks for a session and one doesn't exist. There are a couple of reasons for this but first we can't always go back and change working code so we have a mix of applications that range from no SQL, strait JDBC, iBatis, and Hibernate.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 12 posts ] 

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.