概要

変更ログは、変更(挿入、更新、削除イベント)のログを作成するための組み込みのメカニズムを提供します。オプションで実装できる 4 つのインターフェイスがあり、このメカニズムのさまざまな部分を制御するのに使用できます。デフォルトでは、エンティティ Bean に @ChangeLog アノテーションを付け、変更を JSON 形式でロガーに記録できます。

@History と重なるところがあります。これらはデータベース主導のアプローチです。@ChangeLog とは異なり @History はトランザクショナルであり、バイパスできません。

制限事項

SqlUpdate、CallableSql、Update によるバルク更新は変更ログに含まれません。

入門

ステップ 1: 挿入のデフォルトを決定する

挿入は、変更ログに含めるかどうかのデフォルトがあり、これはアプリケーションによって異なります。エンティティ Bean に @ChangeLog アノテーションを付ける際にデフォルトの動作を上書きすることを選択できるため、このことについて事前に考慮することをお勧めします。

デフォルトでは、挿入は含まれます。DatabaseConfig.setChangeLogIncludeInserts(boolean) を使用してデフォルトの動作を制御できます。これは application.properties から設定することもできます。

ebean.changeLogIncludeInserts=false

ステップ 2: @ChangeLog の追加

変更のロギングを有効にする必要があるすべてのエンティティ Bean に @ChangeLog アノテーションを追加します。

@ChangeLog
@Entity
public class Address {
...

/**
 * Only include updates if specific properties are changed.
 */
@ChangeLog(updatesThatInclude = {"name","dateOfBirth"})
@Entity
public class Customer {
...


/**
 * Override the default behaviour for inserts - INCLUDE, EXCLUDE or DEFAULT.
 * In this case exclude inserts from the change log.
 */
@ChangeLog(inserts = ChangeLogInsertMode.EXCLUDE)
@Entity
public class Customer {
...

ステップ 3: ChangeLogPrepare の実装

このステップをスキップして ChangeLogPrepare の実装を提供しない場合、'no op' の実装が使用され、ユーザーのコンテキスト情報(ユーザー ID、ユーザー IP アドレスなど)は設定されません。

通常、ChangeLogPrepare はユーザー ID やユーザー IP アドレスなどのユーザーのコンテキスト情報を取得し、それを change set に設定して実装されます。true を返すと処理が継続し、changeSet がバックグラウンドスレッドの ChangeLogListener に渡されます。

フォアグラウンドでロギングを実行する場合は、prepare メソッドでロギングを呼び出して false を返すことができます(つまり、change set がバックグラウンドスレッドの ChangeLogListener に渡されません)。

class MyChangeLogPrepare implements ChangeLogPrepare {

  @Override
  public boolean prepare(ChangeSet changes) {

    // get user context information typically from a
    // ThreadLocal or similar mechanism

    String currentUserId = ...;
    changes.setUserId(currentUserId);

    String userIpAddress = ...;
    changes.setUserIpAddress(userIpAddress);

    changes.setSource("myApplicationName");

    // add arbitrary user context information to the
    // userContext map
    changes.getUserContext().put("some", "thing");

    return true;
  }
}

ステップ 4: ChangeLogPrepare 実装の登録

ChangeLogPrepare の実装は、クラスパスのスキャニングがオンになっている場合は自動的に検出できます(エンティティ Bean の検出と同じです)。つまり、スキャニングがオンになっている場合は、ChangeLogPrepare の実装を明示的に登録する必要はなく、代わりに検出されてインスタンス化されます。

スキャニングが使用されていない場合、または ChangeLogPrepare 実装に依存関係があり、そのインスタンス化は Ebean の外部で実行する必要がある場合、それを DatabaseConfig に明示的に登録します。

// example code explicitly registering the ChangeLogPrepare implementation

MyChangeLogPrepare changeLogPrepare = ...;

DatabaseConfig config = new DatabaseConfig();
...
// register explicitly here
config.setChangeLogPrepare(changeLogPrepare);


Database database = DatabaseFactory.create(config);
...

ステップ 5: ロギングの設定

ChangeLogListener のデフォルトの実装では、イベントが io.ebean.ChangeLog にログされます。通常、これらのログが別のログに送られるようにロギングを設定する必要があります。

logback xml 設定では、これらの変更イベントを別のログに記録するアペンダー CHANGE_LOG が示されます。

<appender name="CHANGE_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <File>log/changeLog.log</File>
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <FileNamePattern>log/changeLog.log.%d{yyyy-MM-dd}</FileNamePattern>
    <MaxHistory>90</MaxHistory>
  </rollingPolicy>
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>%d{HH:mm:ss.SSS} %msg%n</pattern>
  </encoder>
</appender>

<logger name="io.ebean.ChangeLog" level="TRACE" additivity="false">
  <appender-ref ref="CHANGE_LOG"/>
</logger>