Popup “Unsaved changes” when change only @Transient fields

How can I avoid this behavior?
Sometimes I need to create fields just to show any values on the screens.

Example:
I need to show the fullname user that edited a register of a StantardEntity.
1- Search user by login;
2- Set the fullname on a @MetaProperty and @Transient field;
3- See on the screen :smiley:
3- The message appear when I closet window :frowning:

You can create a read-only attribute like this:

    @Transient
    @MetaProperty(related = {"firstName", "lastName"})
    public String getFullName() {
        return firstName + " " + lastName;
    }

I can’t create a read-only, becouse I need set the value when open the screen controller.

Repair that the createdBy field save the login user, and I need show the fullname.
Then I search by a query, and set the value…

I believe that in this case, the ‘unsaved changes message’ should not appear. I have modified only a transient field, don’t have anything to commit to database.

Any field is a state and should be tracked for changes. When you commit a screen, data doesn’t go directly to the database, it goes through the chain of events where it can be intercepted, changed or redirected: starting from screen event handlers to entity listeners on the middleware. For example, it is a common practice to modify persistent attributes using a transient attribute state before saving the entity.

If you don’t need the state in the entity, why do you create an attribute at all? You could just compute your full name and display it on the screen using the setValue() method of Label or TextField.

1 Like

Hi @knstvk,

@cristiano.cordeiro07 and I work for the same company, so I’ll reply on his behalf.

We used a different approach: instead of setting transient properties on screen load, we moved the logic to an EntityListener (BeforeDetachEntityListener).

After reading the documentation, we knew this was exactly what we need:

This listener can be used for populating non-persistent entity attributes before sending it to the client tier.

Thanks for your help.

Regards,
Peterson.

1 Like

Hi Peterson,

Glad to hear that you found a solution. But be aware that in your case the computation will be performed for all loaded entities of this type, potentially for a lot of them, e.g. loading to a browse screen. So if you query the database it may become a performance issue.

I think we should provide a way in the framework to exclude some attributes from change tracking, so I have filed an issue.

Regards,
Konstantin

2 Likes

An alternative solution for you could be setting your transient attribute in the edit screen just before it is merged into the DataContext. You can do it in the load delegate, for example:

@Install(to = "customerDl", target = Target.DATA_LOADER)
private Customer customerDlLoadDelegate(LoadContext<Customer> loadContext) {
    Customer customer = dataManager.load(loadContext);
    customer.setFullName("...");
    return customer;
}
2 Likes