How to record changes made in one entity in another entity?

Hello,

I would like to record changes made in one entity in another entity to be able to track every updates. For example, when creating or editing a « Product » and saving it, I want to record it in « ProductsHistory » entity as well. Could you please suggest how to achieve it (apart from tracking feature which is within the entity form)?

My solution was as following:

  1. Adding an entity listener in a domain definition file (Product.xml):
<entity-listener class="com.axelor.apps.stock.listener.ProductListener"/>
  1. Calling a service method in ProductListener class:

public class ProductListener {

protected final Logger log = LoggerFactory.getLogger(getClass());

@Inject protected ProductsHistoryService productsHistoryService;

//    @Inject
//    public ProductListener(ProductsHistoryService productsHistoryService) {
//        this.productsHistoryService = productsHistoryService;
//    }

//    @PostUpdate
    @PrePersist
    protected void onPostPersistOrUpdate(Product product) throws AxelorException {
    
        try {
                if (productsHistoryService != null) {
                    productsHistoryService.addNewProductUpdatesToHistory(product);
                } else {
                    log.error("ProductsHistoryService is null. Cannot add new product updates to history.");
                }
            } catch (Exception e) {
                log.error("Error occured in onPostPersistOrUpdate method: {}", e.getMessage(), e);
            }
    }

}

  1. Calling a repository method in the service class:

public interface ProductsHistoryService {

public void addNewProductUpdatesToHistory(Product product);

}

public class ProductsHistoryServiceImpl implements ProductsHistoryService {

protected final Logger log = LoggerFactory.getLogger(getClass());

protected ProductsHistoryRepository productsHistoryRepo;

@Inject
public ProductsHistoryServiceImpl(ProductsHistoryRepository productsHistoryRepo) {
    this.productsHistoryRepo = productsHistoryRepo;
}

@Transactional
@Override
public void addNewProductUpdatesToHistory(Product product) { 

    if (productsHistoryRepo != null) {
        productsHistoryRepo.addNewProductUpdatesToHistory(product);
    } else {
        log.error("ProductsHistoryRepository is null");
    }
}

}

  1. Performing a save in « ProductsHistory.xml »:
<entity name="ProductsHistory" repository="default">

    <many-to-many name="product" ref="com.axelor.apps.base.db.Product" title="Product"/>

    <string name="title" title="Title" namecolumn="true" required="true"/>
    <string name="productStatus" title="Status"/>
    <decimal name="salePrice" title="Price"/>
    <datetime name="applicationBeginDateTime" title="Application begin date"/>
    <datetime name="applicationEndDateTime" title="Application end date"/>


    <extra-imports>
        <![CDATA[
            import org.slf4j.Logger;
            import org.slf4j.LoggerFactory;
            import com.axelor.apps.base.db.Product;

            import javax.persistence.EntityManager;
            import javax.persistence.PersistenceContext;
            import javax.transaction.Transactional;
        ]]>
    </extra-imports>

    <extra-code>
        <![CDATA[

        protected final Logger log = LoggerFactory.getLogger(getClass());
        
        log.info("saving ProductsHistory instance: {}");

        ProductsHistory productsHistory = new ProductsHistory();
        productsHistory.setTitle(product.getName());
        productsHistory.setProductStatus(product.getProductStatus());
        productsHistory.setSalePrice(product.getSalePrice());
        productsHistory.setApplicationBeginDateTime(product.getStartDateTime());
        productsHistory.setApplicationEndDateTime(product.getEndDateTime());

        try {

            this.save(productsHistory);

        } catch (Exception e) {
            log.error("Error saving ProductsHistory instance: {}", e.getMessage());
        }
    ]]>
    </extra-code>
</entity>

I’m getting: « TariffsHistoryService is null. Cannot add new tariff updates to history. », which I think that there might be a problem with dependency injection.