DataContext.PreCommit event isn't fired on browser screen controller

Hi Cuba-Platform followers,

I have an Entity’s browser screen and I want to add some bussiness logic when the user deletes a record, before the action is committed.

I subscribe to the DataContext.PreCommitEvent event in the handler class and include the appropriate code, but the event is not raised when the application runs. Testing all other DataContext events does not execute any either.

Technicals details:

  • Cuba Platform version: 7.1.1
  • Cuba Studio version: 12.0
  • In the some Project there are some entities and UI screens created by Studio 6.10, with platform 6.1x, but the entity in question and their screens was created under Platform 7, with Studio 11.x

image

package com.company.logistica.web.screens.cobrament;

import com.haulmont.cuba.core.entity.Entity;
import com.haulmont.cuba.gui.Notifications;
import com.haulmont.cuba.gui.model.DataContext;
import com.haulmont.cuba.gui.screen.*;
import com.company.logistica.entity.Cobrament;
import javax.inject.Inject;
import com.company.logistica.service.CobramentService;
import java.util.Iterator;
import java.util.Collection;


@UiController("logis_Cobrament.browse")
@UiDescriptor("cobrament-browse.xml")
@LookupComponent("cobramentsTable")
@LoadDataBeforeShow

public class CobramentBrowse extends StandardLookup<Cobrament> {
    @Inject
    private CobramentService cobramentService;
    @Inject
    private Notifications notifications;

    @Subscribe(target = Target.DATA_CONTEXT)
    public void onPreCommit(DataContext.PreCommitEvent event) {
        //TODO Revisar xq no salta l'event
        Collection<Entity> cobraments_elim;
        notifications.create().withCaption("PreCommitEvent").show();
        cobraments_elim =  event.getRemovedInstances();
        for (Iterator<Entity> iterator = cobraments_elim.iterator(); iterator.hasNext();){
            Cobrament cobrament = (Cobrament) iterator.next();
            cobramentService.baixaCobrament(cobrament);
        }
    }

    @Subscribe(target = Target.DATA_CONTEXT)
    public void onPostCommit(DataContext.PostCommitEvent event) {
        notifications.create().withCaption("PostCommitEvent").show();
    }

    @Subscribe(target = Target.DATA_CONTEXT)
    public void onChange(DataContext.ChangeEvent event) {
        notifications.create().withCaption("onChangeEvent").show();
    }

}

I would be very grateful if someone could help me with this trouble.

Thanks in advance

Hi Xavier,

The DataContext listeners are not invoked because Remove action doesn’t use the data context change tracking and commit mechanism. You can see it in the RemoveOperation.commitIfNeeded() - the entities are removed directly using DataManager and then evicted from DataContext. Moreover, DataContext is usually read-only in browser screens (see the attribute of <data> element) so it doesn’t track changes.

You can intercept the remove events if you subscribe to the action as demonstrated below.

public class CustomerBrowse extends StandardLookup<Customer> {

    @Inject
    private RemoveOperation removeOperation;
    @Inject
    private GroupTable<Customer> customersTable;
    @Inject
    private Notifications notifications;

    @Subscribe("customersTable.remove")
    public void onCustomersTableRemove(Action.ActionPerformedEvent event) {
        removeOperation.builder(customersTable)
                .beforeActionPerformed(beforeActionPerformedEvent -> {
                    System.out.println("before remove");
                })
                .afterActionPerformed(afterActionPerformedEvent -> {
                    notifications.create().withCaption("Done!").show();
                })
                .withConfirmation(true)
                .remove();
    }
}

Thanks, Konstantin, for your detailed answer.
I try it and it works fine.
Thanks a lot !