Ошибка изменения объекта

Добрый день.

У меня есть два слушателя, которые срабатывают последовательно и при этом вызывают методы сервиса. Эти методы изменяют один и тот же объект в БД. При этом возникает ошибка “Объект ААА был изменен в другой транзакции.”

Как можно решить данную проблему?

Методы сервиса:

 public void reduceReservedQuantity(Inventory inventoryLine, double quantity){
        try (Transaction tx = persistence.createTransaction()) {
            EntityManager em = persistence.getEntityManager();
            inventoryLine.setQuantityReserved(inventoryLine.getQuantityReserved()-quantity);
            em.merge(inventoryLine);
            tx.commit();
        }
    }

public void reduceExpectedQuantity(Inventory inventoryLine, double quantity){
        try (Transaction tx = persistence.createTransaction()) {
            EntityManager em = persistence.getEntityManager();
            inventoryLine.setQuantityExpected(inventoryLine.getQuantityExpected()-quantity);
            em.merge(inventoryLine);
            tx.commit();
        }
    }

Спасибо.

Если правильно понял ситуацию, подгрузка актуального экземпляра inventoryLine и дальнейшая работа с ним должна помочь:
inventoryLine = em.find(Inventory.class,inventoryLine.getId());

1 симпатия

Спасибо! Помогло. А не могли бы Вы пояснить с точки зрения теории, как это работает и с каким экземпляром работал я без вызова find()? Либо дадите ссылку, где можно почитать.

Насколько понимаю, в методе (слушателе), вызывающем reduceReservedQuantity и reduceExpectedQuantity Вы хранили экземпляр сущности inventoryLine, он имеет версию n. После первого коммита транзакции версия становится n+1, а в следующий метод Вы опять передаете старый экземпляр сущности (n), на что система и ругается.
Если Вы всегда последовательно выполняете эти операции, то так же вариантом будет использовать одну транзакцию или возвращение измененного экземпляра и работа с ним: inventoryLine = em.merge(inventoryLine); /*...*/ return inventoryLine

Методы вызывают два разных слушателя. В этом случае все равно хранится один экземпляр сущности inventoryLine?
Данные методы могут вызываться в произвольном порядке, поэтому лучше использовать метод с find().

Спасибо за разъяснение.

1 симпатия