For easy access and search functionality I want to persist the total amount value of all invoice entries directly in the invoice entity. I wanted to put that logic into a lifecycle callback, but when I change an entry amount only the callback for this invoice entry is fired. Is there a way to propagate the callback also to the parent entity of the composition, if the child changes?
I know I can do it in the screen onPreCommit, but I wanted to know if I can put the logic in a more generic place.
@belyaev A question to the transaction listener. If I reload an entity with the entityManager during beforeCommit like entityManager.reload(entity, "invoiceEntry-txlistener-view") I sometimes run into a org.eclipse.persistence.exceptions.DatabaseException
After investigation of the problem, I see that EclipseLink will perform a flush before the entity reload. Is there a way to prevent this behaviour?
Why do you need reloading data inside the transaction? I guess all attributes are available for you when you use the entity manager, because the entity is attached to the transaction context.
The debugger shows that the InvoiceEntry is managed, but the Invoice is not managed. You need to fetch it from the DB to attach it to the transaction context or invoke merge before trying to access unfetched attributes.
reload() is not nessesary, find() or merge() attach an entity to the persistence context:
public interface EntityManager {
/**
* Merge the state of the given entity into the current persistence context.
* <p>If a new or patch entity (see {@code PersistenceHelper} methods) with non-null ID is passed to merge,
* EntityManager loads the corresponding object from the database and updates it with non-null values
* of attributes of the passed entity. If the object does not exist in the database, the passed entity is persisted
* and returned.
*
* @param entity entity instance
* @return the instance that the state was merged to
* @throws IllegalArgumentException if instance is not an entity or is a removed entity
* @see com.haulmont.cuba.core.global.PersistenceHelper#isNew(Object)
* @see com.haulmont.cuba.core.global.PersistenceHelper#makePatch(BaseGenericIdEntity)
*/
<T extends Entity> T merge(T entity);
Note that implicit flush would not occur if you don’t specify the view with reload.
// implicit flush
entity = entityManager.reload(entity, "invoiceEntry-txlistener-view")
// NO implicit flush, all necessary references will be fetched lazily when inside of transaction
entity = entityManager.reload(entity)