[hibernate-dev] [OGM] Demarcating units of work

Gunnar Morling gunnar at hibernate.org
Wed May 6 05:01:29 EDT 2015


When talking to people about OGM, there is always that awkward moment when
you need to explain that TX demarcation is required also for
non-transactional data stores.

While it makes sense for our purposes (we use the "TX cycle" to optimise
the work sent to the backend etc.), I can understand people who find that
odd API-wise. So I was thinking about how this could be improved.

When it comes to CDI, a more "neutral" annotation (and a portable extension
examining it) than @Transactional could be helpful:

    public void saveOrderAndCustomer(Order order, Customer customer) {
        session.persist( order );
        session.persist( customer );

By means of the @UnitOfWork annotation it would be expressed that the
entire method should run as one "transaction". This also could be used to
specify an error handler for our new API to be applied for this unit of

    public void saveOrderAndCustomer(Order order, Customer customer) { ... }

In non-managed environments, Java-8-style Lambda expressions could be
leveraged nicely to achieve the same:

    session.runUnitOfWork( () -> {
        session.persist( order );
        session.persist( customer );

This should feel much nicer to e.g. users of the MongoDB backend than
invoking session.getTransaction().begin()/commit(). It also plays greatly
together with the error handling stuff:

    session.buildUnitOfWork( () -> {
        session.persist( order );
        session.persist( customer );
    } )
    .onFailedGridDialectOperation( context -> {
        // e.g. log failed op
        return ErrorHandlingStrategy.ABORT;
    } )
    .onRollback( context -> {
        // e.g. log applied ops
    } )

Of course something equivalent could be done for Java 7, but it'd probably
look not as concise.

Any thoughts?



More information about the hibernate-dev mailing list