このように定義されたバージョン列があります
@org.springframework.data.annotation.Version
protected long version;
Spring Data JDBC では、常に INSERT を試みます。更新が行われていません。PersistentEntityIsNewStrategy
デバッグすると、デフォルトの戦略であるが使用されていることがわかります。永続化されてisNew()
いるエンティティの状態を判断するメソッドがあります。バージョンとIDがこの決定に使用されていることがわかります。
しかし、私の質問は、2 回目.save()
に呼び出されたときにisNew()
メソッドが false を返すことができるように、保存するたびにバージョン列をインクリメントする責任があるのは誰かということです。
BeforeSaveEvent
バージョン列のインクリメントを起動して処理する必要がありますか? を処理するにはそれで十分でしょうOptimisticLock
か?
編集 このように BeforeSaveEvent をリッスンする ApplicationListener を追加しました。
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);
}
}
};
}
したがって、バージョン列は機能しますが、残りの監査可能フィールド@CreatedAt, @CreatedBy,@LastModifiedDate and @LastModifiedBy
は設定されていません!!
編集2
以下のように新しい 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;
}
}