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:
- Adding an entity listener in a domain definition file (Product.xml):
<entity-listener class="com.axelor.apps.stock.listener.ProductListener"/>
- 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);
}
}
}
- 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");
}
}
}
- 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.