2
1

More than 3 years have passed since last update.

Spring BatchでBeanを入れ子にすると正常に処理されない問題の解決方法

Posted at

概要

たとえば、Chunk指向Taskletを表すクラスを作成しようと FlatFileItemReaderBuilder, ItemProcessor, JdbcBatchItemWriterBuilder を保持するクラスを定義したくなるかもしれない。

しかしながら、このクラスを Bean として登録しても JdbcBatchItemWriterBuilder は下記のようなエラーが出て正常に動作しない。

出力されるエラー
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)]; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: SQLステートメントに文法エラーがあります "INSERT INTO PEOPLE (FIRST_NAME, LAST_NAME) VALUES (:[*]FIRSTNAME, :LASTNAME)"; 期待されるステートメント "), DEFAULT, NOT, EXISTS, INTERSECTS, UNIQUE"
Syntax error in SQL statement "INSERT INTO PEOPLE (FIRST_NAME, LAST_NAME) VALUES (:[*]FIRSTNAME, :LASTNAME)"; expected "), DEFAULT, NOT, EXISTS, INTERSECTS, UNIQUE"; SQL statement:

なぜか :firstName? に変換されていないのである。
(もちろん JdbcBatchItemWriterBuilder を直接 Bean として登録した場合は正常に動作する。)

原因

Bean はすべて登録した時点で、InitializingBeanimplements しているクラスについては afterPropertiesSet() が呼ばれることで登録が正常に完了する。
しかし、Bean となるべきオブジェクトを入れ子として保持している場合は、これが呼ばれないために正常に登録完了していない状態となるのだ。

解決法

保持している親側のクラス(=直接 Bean として公開されるクラス)で下記のように InitializingBean を実装して保持しているオブジェクトに伝播させる。

@Override
public void afterPropertiesSet() throws Exception {
    Object[] objects = new Object[]{this.reader, this.processor, this.writer};
    for (Object object : objects) {
        if (object instanceof InitializingBean) {
            ((InitializingBean) object).afterPropertiesSet();
        }
    }
}
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1