Optimistic lock exception - correct handling

Hi,

When an optimistic lock exception occurs, what is the recommended way of handling this? Currently I let the default pop up come on the screen stating that the entity cannot be merged (etc etc). However, it’s not particularly user friendly, and the whole stack trace appears in the log file which means scanning the log file for more serious errors is tricky as you see all the non-serious Optimistic Lock issues.

Also, it might be that I would be able to work out what is different and merge within the code in some cases - is this something that is possible?

Thanks

Hi Mark,

You can intercept the optimistic locking exception in the editor screen as follows:

public class FooEdit extends StandardEditor<Foo> {

    @Inject
    private Notifications notifications;
    @Inject
    private DataManager dataManager;

    @Override
    protected OperationResult commitChanges() {
        try {
            return super.commitChanges();
        } catch (RemoteException e) {
            if (e.contains("javax.persistence.OptimisticLockException")) {
                Foo latestFoo = dataManager.load(Id.of(getEditedEntity())).one();
                notifications.create()
                        .withCaption("Entity was changed")
                        .withDescription(String.format(
                                "version: %d, name: %s", latestFoo.getVersion(), latestFoo.getName()))
                        .show();
                return OperationResult.fail();
            } else {
                throw e;
            }
        }
    }
}

Perhaps you can also try to merge some information from the latest instance stored in the database into the currently edited one. To be able to save it, set the version attribute to the same value as in the latest instance.

As for the log messages, you can get rid of them only if you redefine the ServiceInterceptor bean in your project. Create a subclass, override the logException() as you want, and register your class in spring.xml:

<bean id="serviceInterceptor" class="com.company.demo.core.MyServiceInterceptor">
    <property name="userSessions" ref="cuba_UserSessions"/>
    <property name="persistence" ref="cuba_Persistence"/>
    <property name="statisticsAccumulator" ref="cuba_MiddlewareStatisticsAccumulator"/>
    <property name="configuration" ref="cuba_Configuration"/>
</bean>

It is also a bad idea to hide all OptimisticLockViolation exceptions from log or ignore them.
Sometimes, when you use long transactions or nested transactions or entity listeners / entity changed event, or even when writing custom entity editing code in screens - it is possible to introduce a bug that will always throw an optimistic lock exception, even when record is edited with single user.
So keeping exceptions in logs is essential for debugging.

Thanks both I will give that a try.

Alex - agreed that the exception can be useful, I’m hoping to catch and resolve those common causes I have in my implementation currently and anything else will keep the exception