Your transaction handling looks a bit fishy to me. If you don’t want to use declarative transaction management, at least use a dedicated method taking a lambda to abstract this properly e.g.
public class HibernateUtil {
...
public static void inTransaction(User user, Consumer<Session> function) {
try ( Session session = getSession( user ) ) {
final Transaction txn = session.getTransaction();
txn.begin();
try {
function.accept( session );
}
catch (Throwable e) {
try {
txn.rollback();
}
finally {
throw e;
}
}
if ( !txn.getRollbackOnly() ) {
txn.commit();
}
else {
txn.rollback();
}
}
}