JPA: существующая сущность не обновлена - PullRequest
0 голосов
/ 17 декабря 2018

Я столкнулся с проблемой, когда в некоторых очень редких случаях (<1%) существующий объект не обновляется правильно.Во всех остальных случаях он работает как положено. </p>

Стек: JPA и Hibernate, Wildfly10 (кластер), Ubuntu, PostgreSQL (настройка Master / Slave)

Что происходит?

  1. Пользователь ожидает в своем браузере, что для ContractEntity установлено значение PAID.Браузер выполняет запрос каждые 3 секунды, запрашивая статус ContractEntity
  2. Наш поставщик платежей вызывает на нашем сервере веб-крючок, который вызывает функцию setContractToPaidAndNotifyUsers().Это должно изменить статус ContractEntity на PAID, но он останется в статусе STARTED.Нет зарегистрированных ошибок, и другие вызовы функций, которые происходят впоследствии, работают правильно (отправка электронных писем).

Поэтому я предполагаю, что ошибка происходит, когда транзакция базы данных совершается.

Это функция, которую вызывает webhook:

@Stateless
public class ContractBoundary {

    @Inject
    private ContractControl contractControl;


    private void setContractToPaidAndNotifyUsers(PaymentEntity paymentEntity, ContractEntity contractEntity, final String paidResourceId) {

        // This is not working (no error, but the contract remains on status STARTED
        contractEntity.setStatus(ContractStatusEnum.PAID);
        contractEntity.setPaidResourceId(paidResourceId);
        ContractEntity updatedContractEntity = contractControl.update(contractEntity);

        // These are working
        mailControl.sendMoneyArrivedMailToPayee(
                contractBoundary.getContractLink(updatedContractEntity.getContractCode()),
                updatedContractEntity.getTitle(), updatedContractEntity.getPayer(), updatedContractEntity.getPayee(),
                eventMoneyArrivedForPayee);
        mailControl.sendMoneyArrivedMailToPayer(
                contractBoundary.getContractLink(updatedContractEntity.getContractCode()), contractEntity.getTitle(),
                updatedContractEntity.getPayer(), updatedContractEntity.getPayee(), eventMoneyArrivedForPayer);


        }
}

Это функция обновления в contractControl

public class ContractControl extends BasicCrudControl {

    // ... more CRUD functions

    public ContractEntity update(final ContractEntity contract) {
        ContractEntity update = super.update(contract);
        return update;
    }
}

Это функция обновления нашего BasicCRUDControl:

protected <T> T update(final T entityToUpdate) {
    T t = this.em.merge(entityToUpdate);
    return t;
}

Нужно ли мне запускать em.flush(); или em.refresh(); в моей функции update?Поскольку это происходит только в некоторых случаях, я думаю, что может возникнуть проблема, когда запрос из браузера пользователя выполняется одновременно с вызовом webhook, что может привести к некоторым проблемам.

ТакжеЯ только что узнал, что ContractControl не имеет @Stateless Аннотация, может ли это привести к проблемам, так как ContractBoundary помечен как не имеющий состояния и вводит ContractControl?

Любая помощь приветствуется!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...