package com.commafeed.backend.dao; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.context.internal.ManagedSessionContext; public class UnitOfWork { @FunctionalInterface public static interface SessionRunner { public void runInSession(); } @FunctionalInterface public static interface SessionRunnerReturningValue<T> { public T runInSession(); } public static void run(SessionFactory sessionFactory, SessionRunner sessionRunner) { call(sessionFactory, () -> { sessionRunner.runInSession(); return null; }); } public static <T> T call(SessionFactory sessionFactory, SessionRunnerReturningValue<T> sessionRunner) { final Session session = sessionFactory.openSession(); if (ManagedSessionContext.hasBind(sessionFactory)) { throw new IllegalStateException("Already in a unit of work!"); } T t = null; try { ManagedSessionContext.bind(session); session.beginTransaction(); try { t = sessionRunner.runInSession(); commitTransaction(session); } catch (Exception e) { rollbackTransaction(session); UnitOfWork.<RuntimeException> rethrow(e); } } finally { session.close(); ManagedSessionContext.unbind(sessionFactory); } return t; } private static void rollbackTransaction(Session session) { final Transaction txn = session.getTransaction(); if (txn != null && txn.isActive()) { txn.rollback(); } } private static void commitTransaction(Session session) { final Transaction txn = session.getTransaction(); if (txn != null && txn.isActive()) { txn.commit(); } } @SuppressWarnings("unchecked") private static <E extends Exception> void rethrow(Exception e) throws E { throw (E) e; } }