はじめに
- JPAでクエリメソッドを使用して、RepositoryItemReaderを実装するときの備忘です。
バージョン
- pomから抜粋。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
実装
entity
- 説明に最低限必要な物だけ。
Company.java
@Data
@Entity
public class Company implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="company_id")
private int companyId;
@Column(name="category_id")
private int categoryId;
}
repository
- findByCategoryIdが今回対象のクエリメソッドです。
CompanyRepository.java
@Repository
public interface CompanyRepository extends JpaRepository<Company, Integer> {
public Page<Company> findByCategoryId(int categoryId, Pageable pageable);
}
本処理部
BatchConfiguration.java
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
CompanyRepository companyRepository;
@Bean
public RepositoryItemReader<Company> reader() {
RepositoryItemReader<Company> reader = new RepositoryItemReader<>();
reader.setRepository(companyRepository);
// クエリメソッド指定。タイプセーフにしたい。
reader.setMethodName("findByCategoryId");
// クエリメソッドの引数指定
List<Object> arguments = new ArrayList<>();
arguments.add(CategoryCode.BANK);
reader.setArguments(arguments);
// 取得結果のソート
Map<String, Direction> sort = new HashMap<>();
sort.put("companyId", Direction.ASC);
reader.setSort(sort);
return reader;
}
// 以降、その他の処理
ポイント
- クエリメソッドはPageableでの実装が必須のようです。
たとえばrepositoryの実装が以下のようになっているとします。
public List<Company> findByCategoryId(int categoryId);
この実装でバッチを実行すると以下の様なエラーが出ます。
java.lang.NoSuchMethodException: com.sun.proxy.$Proxy66.findByCategoryId(java.lang.Integer, org.springframework.data.domain.PageRequest)
- ItemReaderの実装で、ソートの指定も必須のようです。
こちらも指定しないと例外が発生します。