no_ejb wrote:
An very simple example:
method1 inovke Threadlocal to get session, it triggers session creation.
method1 calls method2 which gain the existing session and function returns. Who close the session? well of course method1. but method2 can be invoked independly, so it has to close the session. So you will start seeing people inventing reference count into picture, that is exactly what Java tells us NOT to do. Why? Crash of one method could lead to reference count asymetric, and don't tell me put it into finally block, because that doesn't work nicely sometimes(such as you crashed before you getting the session) and defeats the purpose of simplicity of this pattern anyway.
If you are willing to follow the IoC pattern similar to Spring, you could do the following (note this is a simple example, you could easily start adding interfaces, etc, but then you should really consider Spring since it already does this)
Code:
public abstract class HibernateBlock {
public abstract Object runInHibernate(Session session) throws HibernateException;
public void execute() throws HibernateException {
boolean wasSessionCreated = false;
Session session = (Session)someThreadLocal.get();
if (session == null) {
session = someHibernateSessionFactory.createSession();
wasSessionCreated = true;
}
try {
runInHibernate(session);
} finally {
if (wasSessionCreated) {
session.close();
}
}
}
And then to use this block:
Code:
public Object someMethod(final Object param1) {
Object result = new HibernateBlock() {
public Object runInHibernate(Session session) {
// do stuff with the hibernate session
}
}
return result;
}
There are some things that will be awkward with this approach such as the syntax of the anonymous inner class, needing to declare method parameters final, having to cast the result object from the block, and somewhat quirky dealing with typed exceptions, but it solves exactly the problem you presented.
Some of the awkwardness can be resolved if you turn to AOP (which is one technique that Spring offers, but doesn't require).
At any rate, there are options out there that aren't that difficult.
[/code]