My Java application uses Hibernate as an ORM framework. I find myself often writing code like this:
Session session = HibernateUtil.getSessionFactory().openSession();
try {
session.beginTransaction();
// do some work, which might or might not yield a result which will be returned
doWork(session);
// it also might involve using and changing local variables, like success and failure counters
session.getTransaction().commit();
return result;
} catch (Exception e) {
// optional: log the exception
Utility.logException("some log node", e);
// Also, some other actions like sending an alert email might happen at this place.
if (session.getTransaction().isActive()) {
session.getTransaction().rollback();
}
// optional: rethrow the exception
//throw e;
} finally {
if (session.isOpen()) {
session.close();
}
}
and I'm wondering if there is a good way to put this 'boilerplate' code in a single method. The doWork
often (but not always) involves modifying local variables.
If this was a C# application, I'd just create a method like this:
public static void DoWorkInSession(Action<Session> workToDo, String logNode, bool rethrowException)
and call the workToDo
Action inside the method.
Using reflection (which I already do at some places) only resolves the problem partially, and makes logging errors less convenient with the 'InvocationTargetException's. Are there any other (better) ways to do this, e.g. using Java 8 functionalities which I'm slowly beginning to discover?