概要
たとえば、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 はすべて登録した時点で、InitializingBean
を implements
しているクラスについては 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();
}
}
}