What is the purpose of the Hibernate ReturningWork<Long> interface?

Hibernate Session Hibernate Session doReturningWork

The Hibernate Session doReturningWork method has the following signature:

<T> T doReturningWork(ReturningWork<T> work) throws HibernateException;

And the ReturningWork interface looks as follows:

public interface ReturningWork<T> {
    public T execute(Connection connection) throws SQLException;
}

So, unlike the doWork method, the doReturningWork allows us to return an object to the method caller.

For example, we can use the doReturningWork method to get the current transaction isolation level:

Session session = entityManager.unwrap(Session.class);

int isolationLevel = session.doReturningWork(
    connection -> connection.getTransactionIsolation()
);

assertEquals(
    Connection.TRANSACTION_READ_COMMITTED, 
    isolationLevel
);

When to use doWork and doReturningWork?

In general, you can use the JPA or Hibernate-specific API to execute SQL statements or call database procedures or functions.

However, if you want to get access to the underlying JDBC Connection method and execute any possible operation via the JDBC API, then you need to use the doWork and doReturningWork Hibernate Session methods.


As I explained in more details on my blog, you can use the ReturningWork and the Work interfaces to implement any logic that requires direct access to the java.sql.Connection used by your Hibernate session.

Here is a simple example that uses the ReturningWork interface to execute a very simple query (which you could also implement with JPQL) and return the result.

Session session = em.unwrap(Session.class);
Integer bookCount = session.doReturningWork(new ReturningWork<Integer>() {

    @Override
    public Integer execute(Connection con) throws SQLException {
        // do something useful
        try (PreparedStatement stmt = con.prepareStatement("SELECT count(b.id) FROM Book b")) {
            ResultSet rs = stmt.executeQuery();
            rs.next();
            return rs.getInt(1);
        }
    }
});

log.info("Found " + bookCount + " books.");