How to do it...

Perform the following steps to complete this recipe:

  1. First, we need to define our persistence unit:
  <persistence-unit name="ch02-batch-pu" >
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:app/userDb</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-
generation.database.action"
value="create"/>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform
.internal.SunOneJtaPlatform"/>
</properties>
</persistence-unit>

  1. Then, we need to declare a User entity:
@Entity
@Table(name = "UserTab")
public class User implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@NotNull
private Integer id;

private String name;

private String email;

public User() {
}

//DO NOT FORGET TO IMPLEMENT THE GETTERS AND SETTERS
}
  1. Here, we're creating a job reader:
@Named
@Dependent
public class UserReader extends AbstractItemReader {

private BufferedReader br;

@Override
public void open(Serializable checkpoint) throws Exception {
br = new BufferedReader(
new InputStreamReader(
Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream
("META-INF/user.txt")));
}

@Override
public String readItem() {
String line = null;

try {
line = br.readLine();
} catch (IOException ex) {
System.out.println(ex.getMessage());
}

return line;
}
}
  1. Then, we need to create a job processor:
@Named
@Dependent
public class UserProcessor implements ItemProcessor {

@Override
public User processItem(Object line) {
User user = new User();

StringTokenizer tokens = new StringTokenizer((String)
line, ",");
user.setId(Integer.parseInt(tokens.nextToken()));
user.setName(tokens.nextToken());
user.setEmail(tokens.nextToken());

return user;
}
}
  1. Here, we're creating a job writer:
@Named
@Dependent
public class UserWriter extends AbstractItemWriter {

@PersistenceContext
EntityManager entityManager;

@Override
@Transactional
public void writeItems(List list) {
for (User user : (List<User>) list) {
entityManager.persist(user);
}
}
}
  1. The processor, reader, and writer are referenced by the acess-user.xml file, which is located at META-INF.batch-jobs:
<?xml version="1.0" encoding="windows-1252"?>
<job id="userAccess"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
version="1.0">
<step id="loadData">
<chunk item-count="3">
<reader ref="userReader"/>
<processor ref="userProcessor"/>
<writer ref="userWriter"/>
</chunk>
</step>
</job>
  1. And finally, we create a bean to interact with the batch engine:
@Named
@RequestScoped
public class UserBean {

@PersistenceContext
EntityManager entityManager;

public void run() {
try {
JobOperator job = BatchRuntime.getJobOperator();
long jobId = job.start("acess-user", new Properties());
System.out.println("Job started: " + jobId);
} catch (JobStartException ex) {
System.out.println(ex.getMessage());
}
}

public List<User> get() {
return entityManager
.createQuery("SELECT u FROM User as u", User.class)
.getResultList();
}
}
  1. For the purpose of this example, we are going to use a JSF page to run the job and load the data:
 <h:body>
<h:form>
<h:outputLabel value="#{userBean.get()}" />
<br />
<h:commandButton value="Run" action="index" actionListener="#{userBean.run()}"/>
<h:commandButton value="Reload" action="index"/>
</h:form>
</h:body>

Run it on a Jakarta EE server to load the web page. Click on the Run button and then the Reload button.