DeltaSpike Data Module provides capabilities for implementing repository patterns and thereby simplifying the
repository layer not unlike Spring Data. In this post we will take a JPA project and
rewrite the repository layer to use DeltaSpike Data. Basically, we will strip off the boilerplate
EntityManager queries and enable centralization of query logic and consequently reducing code duplication
and improve testability.
At the end of this guide our folder structure will look similar to the following:
. |__src/ | |__main/ | | |__java/ | | | |__com/ | | | | |__juliuskrah/ | | | | | |__cdi/ | | | | | | |__ApplicationResources.java | | | | | | |__business/ | | | | | | | |__CustomerService.java | | | | | | | |__dto/ | | | | | | | | |__CustomerBean.java | | | | | | | |__mapper/ | | | | | | | | |__CustomerMapper.java | | | | | | |__entity/ | | | | | | | |__Customer.java | | | | | | |__repository/ | | | | | | | |__CustomerRepository.java | | | | | | |__web/ | | | | | | | |__IndexController.java | | |__resources/ | | | |__db/ | | | | |__migration/ | | | | | |__`V1__Create_customer_table.sql` | | | |__META-INF/ | | | | |__persistence.xml | | | |__modules/ | | | | |__com/ | | | | | |__h2database/ | | | | | | |__h2/ | | | | | | | |__main/ | | | | | | | | |__module.xml | | | |__project-defaults.yaml | | |__webapp/ | | | |__WEB-INF/ | | | | |__templates/ | | | | | |__default.xhtml | | | | |__beans.xml | | | | |__web.xml | | | |__index.html | | | |__index.xhtml |__pom.xml
C:\> mvn clean wildfly-swarm:run
Wait for all the dependencies to download and
swarm to start.
Add the DeltaSpike Data dependencies:
Replace the code in
There are a few things to note here. The
@Repository annotation tells the extension that this is a
repository for the
Customer entity. Any method defined on the repository will be processed by the framework.
EntityRepository Interface is mainly intended to hold complex query logic, working with both a
repository and an
EntityManager in the service layer might unnecessarily clutter code.
The top base type is the
EntityRepository interface, providing common methods used with an
DeltaSpike Data module supports also annotating methods for more control on the generated query using
@Query. If the JPQL query requires named parameters to be used, this can be done by annotating the
arguments with the
For all these to work, DeltaSpike Data requires an
EntityManager exposed via a CDI producer - which is
common practice in Java EE applications:
@Produces @PersistenceContext EntityManager em;
DeltaSpike Data module uses a
ResourceLocalTransactionStrategy as default
demarcating transactions. Our example is configured to use
jta-data-source, and the
ResourceLocalTransactionStrategy does not quite fit our needs here.
Let’s talk a little about JPA transactions to understand our decision not to use
A transaction is a set of operations that either fail or succeed as a unit. Transactions are a fundamental
part of persistence. A database transaction consists of a set of SQL DML (Data Manipulation Language)
operations that are committed or rolled back as a single unit. An object level transaction is one in which a
set of changes made to a set of objects are committed to the database as a single unit.
JPA provides two mechanisms for transactions. When used in Java EE JPA provides integration with JTA (Java
Transaction API). JPA also provides its own
EntityTransaction implementation for Java SE and for use in a
non-managed mode in Java EE. Transactions in JPA are always at the object level, this means that all changes
made to all persistent objects in the persistence context are part of the transaction.
Resource local transactions are used in Java SE, or in application managed (non-managed) mode in Java EE. To
use resource local transactions the transaction-type attribute in the
persistence.xml is set to
RESOURCE_LOCAL. Local JPA transactions are defined through the
EntityTransaction class. It contains basic
transaction API including
JTA transactions are used in Java EE, in managed mode (CMT). To use JTA transactions the transaction-type
attribute in the
persistence.xml is set to
JTA. JTA transactions are defined through the JTA
JTA transactions can be used in two modes in Java EE. In Java EE managed mode such as an
@PersistenceContext, this mode is also known as Container Managed Transaction (CMT).
The second mode allows the
EntityManager to be application managed, (normally obtained from an injected
EntityManagerFactory, or directly from JPA Persistence) also known as Bean Managed Transaction (BMT). This
allows the persistence context to survive transaction boundaries, and follow the normal
life-cycle similar to resource local.
DeltaSpike has three implementations of
We have to tell DeltaSpike to use
We have been introduced to DeltaSpike Data Module, and we saw how easy it is to use for contructing queries. We also did a quick introduction to Transactions in JPA.
As usual you can find the full example to this guide in the github repository. Until the next post, keep doing cool things .