JSR352-Batch Applicationを試してみた(Batchlet編) - しおしお(´・ω・`)の続編です。
今回は、Batchletでデータベースにアクセスしてみようかなと。データベースへのアクセス方法は、JPA使ってもいいし、素のJDBCやオープンソースのライブラリを使ってもいいでしょう。
今回は、JPAを使ってみます。JPAを使った場合、Batchletの実装ではJTAのトランザクションが開始されていないので、Batchretで新しいトランザクションを開始して上げる必要があります。
※Bachletの処理は下の流れで行われると仕様に書かれているので、Batchletでデータベースアクセスするのってあんまり想定されていないんかなと思ったり。でも、ガツンと一発で処理したいときはBatchletでやりたいしなぁと
11.4 Regular Batchlet Processsing 1. <Create StepContext> 2. <Store step level properties in StepContext> 3. <->[StepListener.beforeStep...] // thread A 4. <->Batchlet.process // thread A 5. // if stop issued: 6. <->[Batchlet.stop] // thread B, StepContext is available 7. <->[StepListener.afterStep...] // thread A 8. <Store StepContext persistent area> 9. <Destroy StepContext>
さっそく実装例を簡単に。。。
Batchlet実装
ジョブ定義で指定した数分のデータをJPAを使って登録しているだけのBatchletです。登録件数のフィールドがStringになっているのは、参照実装がBatchPropertyで数値を使えないので・・・。(JBeretはString以外の型も使いそうなのはサポートしてくれているのですがね。)
package siosio.batchlet; import javax.batch.api.AbstractBatchlet; import javax.batch.api.BatchProperty; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.inject.Named; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.transaction.Transactional; import javax.transaction.Transactional.TxType; import siosio.entity.UserEntity; @Dependent @Named @Transactional(TxType.REQUIRES_NEW) public class DbAccessBatchlet extends AbstractBatchlet { @PersistenceContext(unitName = "batch") EntityManager em; @Inject @BatchProperty String count; @Override public String process() throws Exception { final int insertCount = Integer.parseInt(count); for (int i = 0; i < insertCount; i++) { em.persist(new UserEntity("name_" + (i + 1))); } return "SUCCESS"; } }
Entityの実装
IDと属性を1つだけ持ったEntityを作っています。とりあえず、動かすことが目的なのでこの程度で十分でしょうと。
package siosio.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.NamedQuery; import javax.persistence.Table; @Entity @Table(name = "users") public class UserEntity { private Long id; private String name; public UserEntity() { } public UserEntity(String name) { this.name = name; } @Id @GeneratedValue public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
ジョブ定義ファイル
上で作ったBatchletをステップに指定しています。countプロパティに50を指定しているので、50レコードが登録されます。
<job id="db-access-job" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> <step id="clear-users"> <batchlet ref="dbAccessBatchlet"> <properties> <property name="count" value="50" /> </properties> </batchlet> </step> </job>
persistence.xml
特にこれといって何もありません。。。
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1"> <persistence-unit name="batch" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/jbatch</jta-data-source> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="javax.persistence.schema-generation.database.action" value="create" /> <property name="eclipselink.logging.level" value="fine" /> </properties> </persistence-unit> </persistence>