Refresh edit screen data after commit to display data created by database trigger

Hi,

I have been chewing over this problem for a while now and have searched through a lot of CUBA posts that don’t quite answer my problem.

For concurrency reasons we have to use a database ON INSERT trigger on our ‘Projects’ table to create our ‘ProjectNoPrefix’ and ‘ProjectNoPostfix’ data.
When i create a new ‘Project’ using the ‘Project.edit’ screen i need to save and commit the data then reload the data from the database to collect the newly created ProjectNoPrefix and ProjectNoPostfix for display to the user.

Unfortunately i cannot use a CUBA sequence instead of the database trigger. I have tried using .getScreenData().loadAll() and a number of other injected data controllers but to no avail.

Any help would be greatly appreciated.

many thanks,

Ben Waddington.

Hi,

Does the generated data appear when you refresh the browser screen manually after closing the editor? If yes, you can invoke the editor manually and reload the edited entity in afterCloseListener using ScreenBuilder API

Hey,

Yep, the data is definitely being created when the row is created in the database and will show in the browser screen after a refresh. how would i override the create method from the browse screen to add the afterCloseListener?
i can think of 3 ways of doing this:

  1. (preferred) on commit i refresh the data in the editor screen, make the ProjectNo. field visible and highlight it (only for new data, not for edited projects). But i do not know how to refresh the data from the database in the editor screen.
  2. On commit use the ScreenBuilder to open another ‘ProjectNo’ screen that contains just the ProjectNo. field and make that load the data from the database for that entity. But i do not know how to force a screen to load an entity using the ScreenBuilder.
  3. After commit and return to the browse screen i refresh the browse screen data and filter it down to the newly created entity. But i do not know how to override the ‘create’ function of the browse screen to do the listener/refresh/filter.

Sorry for the many questions, love the framework but i am still trying to get to grips with it.

All you need to to is to install after commit handler for the “create” or/and “edit” actions and reload the entity from the database. The code might look like this:

    @Install(to = "projectsTable.create", subject = "afterCommitHandler")
    private void projectsTableCreateAfterCommitHandler(Project project) {
        dataManager.load(Project.class)
                .id(project.getId())
                .optional()
                .ifPresent(p -> {
                    projectsDc.replaceItem(p);
                });
    }

See the attached example. Please note that this example uses PostgreSQL database in order to try triggers. trigger-test.zip (80.3 KB)

Unfortunately the solution indicated gave me an 'IllegalStateException: Cannot get unfetched attribute [projectType] from detached object ’ error, presumably because i am using a fairly complex view to load the data?
Marked as solution as i used the ‘projectsTableCreateAfterCommitHandler’ to modify an ‘ID’ parameter on the projectsDl collection loader and reload from the database:

 protected void projectsTableCreateAfterCommitHandler(Project entity)
 {
     projectsDl.setParameter("id", entity.getUuid());
     projectsDl.load();
     projectsDl.removeParameter("id");
 }

Many thanks for the help.

I think it would be better to update the loading operation similar to this: dataManager.load(Project.class).view("project-full-view").id(....

Please refer to the DataManager API, it’s pretty flexible.

Did a little more investigating and this worked perfectly, i just needed to add:
.view(“project-view-browse”)
so that it loaded the data from associated “projectType” entities.

thank you very much!

1 Like