Post database transaction commit hook

Hi.
Is there any way took after commit success?
Without any relation to the UI, at the database level.
Thanks

Hi Avi,

Firstly, you can use a standard mechanism of Spring framework for registering “transaction synchronizations”. Then your class implementing TransactionSynchronization will be called at a desired transaction phase. For example, in a CUBA entity listener (invoked inside a transaction), you can add code which will be executed after successful transaction commit:

package com.company.sales.service;

import com.company.sales.entity.Customer;
import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.listener.BeforeInsertEntityListener;
import com.haulmont.cuba.core.listener.BeforeUpdateEntityListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

@Component("sales_CustomerEntityListener")
public class CustomerEntityListener implements BeforeInsertEntityListener<Customer>, BeforeUpdateEntityListener<Customer> {

    @Override
    public void onBeforeInsert(Customer entity, EntityManager entityManager) {
        printCustomer(entity);
    }

    @Override
    public void onBeforeUpdate(Customer entity, EntityManager entityManager) {
        printCustomer(entity);
    }

    private void printCustomer(Customer customer) {
        System.out.println("In transaction: " + customer);

        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {
                System.out.println("After transaction commit: " + customer);
            }
        });
    }
}

Another option available since CUBA version 6.10 is using EntityChangedEvent. It’s a Spring application event that is sent by the framework when the entity is changed in the database.

The entity must be annotated with @PublishEntityChangedEvents, for example:

@Table(name = "SALES_CUSTOMER")
@Entity(name = "sales$Customer")
@PublishEntityChangedEvents
public class Customer extends StandardEntity {
// ...

In order to receive the event after transaction commit, use @TransactionalEventListener annotation on a middleware bean method, for example:

package com.company.sales.service;

import com.company.sales.entity.Customer;
import com.haulmont.cuba.core.app.events.EntityChangedEvent;
import com.haulmont.cuba.core.global.DataManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

import javax.inject.Inject;
import java.util.UUID;

@Component
public class SomeBean {

    @Inject
    private DataManager dataManager;

    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void onCustomerChanged(EntityChangedEvent<Customer, UUID> event) {
        Customer customer = dataManager.load(event.getEntityId()).one();
        System.out.println("onCustomerChanged: " + customer);
    }
}
1 Like