From: Aapo L. <aap...@pr...> - 2002-12-04 01:39:23
|
> I had a *really* close look into the possibility > that Hibernate issues the unclosed session WARNing > when the session has in fact been closed and I've > concluded that it doesn't. I am quite certain that > the problem is that the user is not closing the > sessions. (In a couple of previous complaints about > this, that turned out to be the case.) Ok it might be my fault (and probably is). Do you see any strange in this: Background: - I have extended Maveric Dispatcher so that it loads Hibernate Session Factory from JNDI and places it in servlet context. Is that proper thing to do? - I have abstract controller that every of my maverick commands extends. - Abstract controller has 2 methods. getSession() that loads Session factory from Servlet context and then opens a new session (if user has already called this.getSession, then it returns previously opened session) and places it in class level variable and then returns it to user. - User then uses session. - User does not close session. - Session is closed in Abstract controller's discard() method that maverick calls automatically after it has served the client (e.g. gui is generated). The proces goes like this: 1. User makes request eg. grid.m that is a maveric command. 2. Maverick initializes NEW controller (the controller extends abstract controller) 3. Then maverick calls execute method. 4. execute method calls this.getSession.find("whatever") <- lazy collection 5. execute method returns a string (that is the view to be rended) 6. Maverick generates a view (view uses lazy collection) 7. Maverick calls discard (that closes a session) The generated HTML (in this case) contains many img tags like this <img src="image.m?id=number" /> So every needed image gets loaded throught Maverick from database. image.m command opens session as above and after sending raw data with proper content-type session get's closed in execute method (Maveric calls discard, but it doesn't do anything cause session is already closed by execute command). The problem is that I have no idea why Hibernate's SessionImpl finalize method tries to close connections that I have already closed (I can output proper log messages when discard is called). What I have found is that if I don't close connections in execute method (prior view), then I sometimes leaves connections open. At least on load testing. If I don't use lazy collections I do not have this problem. > As to the use of finally, cleanup code that *must* > be executed is *exactly* the role of the finally > block, as per any Java textbook. And it is > completely predictable. Method exit cannot occur > without execution of the finally block. Are you > sure the redbook wasn't talking about finalize(), > which *is* unreliable? It's quite long time when I read that, and I could have read it wrong (I checked IBM docs and they all used finally)... and if I think about it, I agree with you. The errors I get about unclosed connections, I get them from SessionImpl finalize(). But problem is not there I think. Is it proper to place SessionFactory in servlet context, or should I always retrieve it from JNDI? I think that JNDI lookup causes some overhead, so I have put the Session factory in servlet context. When I should use Session.disconnect / reconnect instead open and close? Should I set session to null and should I also check if session.close returns an open connection? Do I need to close the connection then manually? Do i need to set connection = null? Kind Regards Aapo <b/>ungle Laakkonen |
From: Aapo L. <aap...@pr...> - 2002-12-04 02:37:32
|
> Where are connections coming from? A Hibernate ConnectionProvider? Or > an application supplied connection? They come from JNDI and I use Hibernate XML configuration and initialize Hibernate with configure();. > What guarantees does Maverick make about when / > wether discard() will be called? Is it *guaranteed* > to be called in the case of an exception, etc? Great questions, :-))))))))))))))))))))). Thanks! Now I'm trying to get Transactions to use JTA. The problem is that I get following warnings: 04:18:56,649 WARN [JTATransactionFactory] No TransactionManagerLookup configured (use of JCS read-write cache is not recommended) What is this setting. I get that warning even if I don't use JCS. This is my hibernate.properties: hibernate.use_outer_join=true hibernate.show_sql=false hibernate.jdbc.batch_size=10 hibernate.statement_cache.size=20 hibernate.transaction.factory_class=cirrus.hibernate.transaction.JTATran sactionFactory hibernate.transaction.manager_class=cirrus.hibernate.transaction.JNDITra nsactionManagerLookup hibernate.query.substitutions yes 'Y', no 'N' jta.UserTransaction=java:comp/UserTransaction And here is Hibernate.cfg.xml: <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-co <hibernate-configuration> <session-factory name="java:comp/env/jndi/HibernateSessionFactory"> <property name="connection.datasource">java:comp/env/jdbc/xa/postgresql/something< /property> <property name="dialect">cirrus.hibernate.sql.PostgreSQLDialect</property> ... mapping files ... </session-factory> </hibernate-configuration> Another warning I get with Resin is: 04:18:57,258 WARN [SessionFactoryObjectFactory] InitialContext did not implement EventContext Should I care about it? |
From: Aapo L. <aap...@pr...> - 2002-12-04 03:10:26
Attachments:
ResinTransactionManagerLookup.java
|
> 04:18:56,649 WARN > [JTATransactionFactory] No TransactionManagerLookup configured > (use of JCS read-write cache is not recommended) Ok there is error in documentation (it's not hibernate.transaction.manager_class). This works: hibernate.transaction.manager_lookup_class=cirrus.hibernate.transaction. ResinTransactionManagerLookup Now it works fine!!!!! Great work! Definately the best O/R tool. --- code --- Here is code for ResinTransactionManagerLookup class: package cirrus.hibernate.transaction; public final class ResinTransactionManagerLookup extends JNDITransactionManagerLookup { /** * @see cirrus.hibernate.transaction.JNDITransactionManagerLookup#getName() */ protected String getName() { return "java:comp/TransactionManager"; } } --- code --- |