1

このように定義されたバージョン列があります

@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呼び出すためです。私はリスナーをまだ運が悪いようにしようとしました。markUpdatedmarkCreatedLOWEST_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;
}

}

4

1 に答える 1