У меня столбец моей версии определен следующим образом
@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;
}
}