-->
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.  [ 13 posts ] 
Author Message
 Post subject: O Great Gurus, respond: Lazy Load does not release conn Why?
PostPosted: Fri Aug 03, 2007 7:51 pm 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
I have a simple question, thoroughly backed up by testing. But rather than present a lot of code and logs, I only want some justification so I understand:

When I do the following:
1) Open a session
2) Begin a transaction
3) Execute a query and get an object
4) Close the transaction BUT NOT THE SESSION
5) On the previous retrieved object, access a lazily initialized list

What I find happening is:
a) On 2 above, a connection is retrieved from the connection pool
b) On 4 above, the connection is released back to the connection pool
c) On 5 above, a connection is quietly retrieved from the connection pool, AND NOT RELEASED AFTER THE LAZILY INITIALIZED LIST IS FULLY INITIALIZED.

The question is why? This connection hangs on to the session until the session is closed. In an application of ours, unclosed sessions were never a problem. When some lazy initialization started occurring due to some code changes, connection leaks have sprouted up everywhere. Why does lazy initialization hold on to connections until the end of the session?

Please explain the wisdom here..

Thank you,

Sundeep


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 04, 2007 6:24 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Connection release mode is documented in "11.5. Connection Release Modes".
Quote:
auto (the default) - this choice delegates to the release mode returned by the org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode() method. For JTATransactionFactory, this returns ConnectionReleaseMode.AFTER_STATEMENT; for JDBCTransactionFactory, this returns ConnectionReleaseMode.AFTER_TRANSACTION. It is rarely a good idea to change this default behavior as failures due to the value of this setting tend to indicate bugs and/or invalid assumptions in user code.


So you're probably using a JDBC transaction factory which will close the connection after the transaction. As you don't start/end another transaction, the connection used to retrieve your lazy loaded collection will remain open until the session closes.

Why don't you close your sessions?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 06, 2007 2:57 pm 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
Thanks for your reply! Yes, I am aware of the connection release mode. However, I still dont understand how the connection release mode of "AFTER_TRANSACTION" logically and unambiguously implies that the connection used for lazy loading must not be released immediately. Lazy loading was done "under the covers" for me, right? So a connection was quietly obtained (ungoverned by any AFTER_TRANSACTION rules). So why wasn't it quietly returned too?

My core problem is this: In the "higher layers" of my app, i.e. the layers that actually consume the objects retrieved by the lower layers, there is a good amount of navigation happening i.e. higher layer requests object A, and then from A navigates to B and from there to C etc. I have the following options:
o Retrieve only A and pass to higher level, leave session open
o Retrieve A and B and C and whatever else, close session, pass the
A-B-C.. tree to higher level
o Retrieve only A and pass to higher level, leave session open, give higher
level some kind of object that it can "close" eventually, which would
close the session

The first option above was what was being used, but obviously is now giving connection leaks. The second option looks very nice, but actually leads to API explosion or object explosion. By "API explosion" I mean, either you have an API for every single type of navigation needed by the higher levels. By "object explosion" I mean that if you dont go the API explosion route, you will probably end up having an API that gets a union of what all your APIs need - so lots of objects will be retrieved in order to satisfy all needs. The third option allows lazy navigation by higher levels, but also entrusts with the higher levels the responsibility of "closing" their interactions with the database. This as we all know is error prone. Generally the developers closer to the DB do a better job of closing off everything, but the developers who dont even know about the DB are less likely to "close" their interactions - they dont even know where there objects are coming from.

Hope you see my problem. Ideally I liked option #1. No problems for higher level developers. A lot of sessions were left open, but were eventually garbage collected - no worries there, because connections never leaked.

Would love to hear about any pattern that resolves this kind of problem..

Thanks,

Sundeep


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 06, 2007 5:10 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
What kind of environment is your application deployed into? If its a web based app you could use "open session in view":
http://www.hibernate.org/43.html

However, some people regard this technique as an anti-pattern:
http://www.realsolve.co.uk/site/tech/or ... rmance.php


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 06, 2007 6:00 pm 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
Thanks again for a quick reply! You are pointing me to all the right resources of course, but on an earlier cursory glance, I had noticed that they had nothing new to offer to me. I guess my own solution #3 is essentially like the "Open Session in View" pattern. In my particular case, my "app" is sometimes in a webapp, sometimes deeper in an appserver. I guess I will end up adopting the OSIV like pattern but I would still love to know why lazy initialization continues holding on to connections, because if it didnt, I wouldnt need any of these solutions.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 1:31 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
thatmikewilliams wrote:
However, some people regard this technique as an anti-pattern:
http://www.realsolve.co.uk/site/tech/or ... rmance.php


This is ridiculous. The author doesn't know how interceptors work and how to solve the n+1 selects problem - which should have triggered his "let's learn more about this" rather than "let's write an article about this" reflex.

The OSIV pattern and its improved siblings (e.g. how Seam is doing it) are the ONLY solution for persistence context management in REAL applications. Learn how it works and why, then write about it.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 2:12 am 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
Christian,

While we have your attention, could also please shed some light on the original query - in a session, why does lazy initialization hold on to a connection even when the lazy initialization is complete?

Also, are there any other critical resources that a session holds on to (i.e. are there any other reasons why sessions should not be left unclosed for the garbage collector to eventually clean up)?

Good to learn from you that the OSIV pattern is in fact not an antipattern... I would be surprised if you had said otherwise..

Thanks much,

Sundeep


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 2:18 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
I have no idea why your stuff doesn't work. My experience and the fact that you are saying "not closing sessions never was a problem before" tells me that your architecture is wrong and probably beyond repair.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 1:41 pm 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
Christian,

Sorry to appear a bit obstinate here, but I believe I understand you but you dont understand me. I completely understand you when you say that the architecture is beyond repair. But essentially, I am only asking for the explanation "WHY doesnt lazy initialization let go of a connection after lazy initialization is complete - why does it hold on to the connection in the session even afterwards". Are there some db level locks that need to be continue to be held? Does some db level transaction need to be open? Does holding on to the connection result in some performance optimization? Must subsequent lazy initializations occur within the same db level transaction? I am struggling to nail down the "why" and I would probably have a hard time deciphering the "why" by looking at the source, so I ask.

This is the only question I really have. The rest (the patterns to follow etc) is well explained in your/Hibernate books and documents and pointless to rehash on the forums.

Thank you for your time,

Sundeep


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 3:07 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Hi Sundeep

The lazy initialisation code is completely separate from the connection management. It can't know whether or not a connection can be released and shouldn't be concerned with such details.

The fact that you can get a connection at all outside the transaction with release mode set to end-of-transaction I believe to be solely an artifact of the implementation. In my opinion it was never anticipated to be used this way. If you read the session in view article, section "can I commit the transaction before rendering the view" (basically what you are doing) it says things like "apparently" you can, "never promoted in hibernate docs" and "this _seems_ to work". Sounds like the authors weren't really sure what the behaviour would be because they didn't expect this kind of usage.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 5:34 pm 
Newbie

Joined: Tue Aug 03, 2004 5:42 pm
Posts: 16
That mike williams (is kewl),
Epiphany! Thanks man. You finally got me exactly to the piece of doc that I shouldnt have glanced over! I'd give you 5 credits if I could..

Sundeep


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 5:35 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Trying to fix an architecture that relies on "not closing sessions" is pointless.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 07, 2007 9:05 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Christian is right of course. Would you consider treating a JDBC connection this way, for example, and expect to get away with it? - no. When an object has a close() method its _always_ for a good reason.

Hibernate does a great job of simplifying lots of the detail involved in data access but there are always "grey areas" in software, usually the result of some implementation details. If you complied strictly with the documented behaviour of connection-release-method: after-transaction you wouldn't have a problem.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 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.