Running background tasks is a useful and important skill in an enterprise context.
You could use it to process data in bulk or just to separate it from the UI processes. This recipe will show you how to do this.
Running background tasks is a useful and important skill in an enterprise context.
You could use it to process data in bulk or just to separate it from the UI processes. This recipe will show you how to do this.
Let's add our dependencies:
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.10.Final</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Perform the following steps to complete this recipe:
<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>
@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
}
@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;
}
}
@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;
}
}
@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);
}
}
}
<?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>
@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();
}
}
<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.
UserReader extends the AbstractItemReader class, which has two key methods – open() and readItem(). In our case, the first one opens the META-INF/user.txt file, while the second one reads each line of the file.
After that, the UserProcessor class extends the ItemProcessor class, which has a processItem() method. It gets the item read by readItem() (from UserReader) to generate the User object that we want.
Once all the items have been processed and are available in a list (in memory), we use the UserWriter class. This extends the AbstractItemWriter class and contains the writeItems method. In our case, we use it to persist the data that we read from the user.txt file.
Now, we just need to use UserBean to run the job:
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());
}
}
The job.start() method is referencing the acess-user.xml file, thereby enabling our reader, processor, and writer to work together.
You can view the full source code for this recipe at https://github.com/eldermoraes/javaee8-cookbook/tree/master/chapter02/ch02-batch.
Change the font size
Change margin width
Change background colour