Столбец @Version не работает из коробки с данными Spring jdbc

У меня столбец моей версии определен следующим образом

@org.springframework.data.annotation.Version
protected long version;

С Spring Data JDBC всегда пытается ВСТАВИТЬ. Обновлений не происходит. Когда я отлаживаю, я вижу, что используется PersistentEntityIsNewStrategy, что является стратегией по умолчанию. У него есть isNew() метод для определения состояния сохраняемой сущности. Я вижу, что для этого определения используются версия и идентификатор.

Но мой вопрос в том, кто отвечает за увеличение столбца версии после каждого сохранения, чтобы при втором вызове .save() метод isNew() мог вернуть false.

Должны ли мы запустить BeforeSaveEvent и обработать увеличение столбца версии? Этого было бы достаточно, чтобы справиться с OptimisticLock?

Изменить. Я добавил ApplicationListener для прослушивания BeforeSaveEvent вот так.

public ApplicationListener<BeforeSaveEvent> incrementingVersion() {
    return event -> {
        Object entity = event.getEntity();
        if (BaseDataModel.class.isAssignableFrom(entity.getClass())) {
            BaseDataModel baseDataModel = (BaseDataModel) entity;
            Long version = baseDataModel.getVersion();
            if (version == null) {
                baseDataModel.setVersion(0L);
            } else {
                baseDataModel.setVersion(version + 1L);
            }
        }
    };
}

Теперь столбец версии работает, но остальные поля Auditable @CreatedAt, @CreatedBy,@LastModifiedDate and @LastModifiedBy не установлены !!

Edit2

Создал новый ApplicationListener, как показано ниже. В этом случае вызываются и мой пользовательский слушатель, и Spring RelationalAuditingListener. Но все же это не решает проблемы. Потому что порядок слушателей [пользовательский, за которым следует весна] заставляет markAudited вызывать markUpdated вместо markCreated, поскольку столбец версии уже увеличен. Я попытался сделать своим Слушателем LOWEST_PRECEDENCE, но все равно не повезло.

Мой пользовательский слушатель здесь

public class CustomRelationalAuditingEventListener
    implements ApplicationListener<BeforeSaveEvent>, Ordered {

@Override
public void onApplicationEvent(BeforeSaveEvent event) {

    Object entity = event.getEntity();
    // handler.markAudited(entity);

    if (BaseDataModel.class.isAssignableFrom(entity.getClass())) {
        BaseDataModel baseDataModel = (BaseDataModel) entity;

        if (baseDataModel.getVersion() == null) {
            baseDataModel.setVersion(0L);
        } else {
            baseDataModel.setVersion(baseDataModel.getVersion() + 1L);
        }
    }
}

@Override
public int getOrder() {
    return LOWEST_PRECEDENCE;
}

}


person Seetharamani Tmr    schedule 22.03.2019    source источник
comment
Не могли бы вы создать отдельный вопрос для проблемы с аудитом или описать, почему, по вашему мнению, она связана с проблемой версии / оптимистической блокировки? В любом случае, пожалуйста, покажите соответствующий код: атрибуты и конфигурация.   -  person Jens Schauder    schedule 24.03.2019
comment
Поля Auditable не были связаны ни с приращением столбца версии, ни с оптимистической блокировкой. Он просто столкнулся с BeforeSaveEvent, запущенным для обработки проверяемых полей, когда я создал BeforeSaveEvent для обработки столбца версии. Но теперь я вижу, что PR существует для обработки увеличения столбца версии. Спасибо!   -  person Seetharamani Tmr    schedule 03.04.2019


Ответы (1)


В настоящее время вам необходимо увеличивать версию вручную, и оптимистическая блокировка отсутствует, т.е. версия используется только для проверки того, является ли сущность новой.

Существует открытая проблема поддержки оптимистической блокировки, и даже существует открытый для этого PR. Поэтому вполне вероятно, что эта функция будет доступна с наступающим этапом 1.1.

person Jens Schauder    schedule 24.03.2019
comment
PR не попал в 1.1, но версия 2.0 Spring Data JDBC будет содержать поддержку оптимистической блокировки. - person Jens Schauder; 02.12.2019