Credit: IBM
Rapidly generate Java Persistence Architecture beans for an enterprise
application
Java™ Persistence API (JPA) entities simplify Java persistence by
using an object-relational mapping approach to define how to map Java
objects to relational database tables in a standard way. In this tutorial,
learn how to create JPA entities using Eclipse Oxygen, IBM WebSphere®
Liberty 17, and Apache Derby 10. I give you step-by-step instructions on
how to build the JPA-based Acme Membership application.
This tutorial focuses on how to create JPA entities that meet the
following requirements:
- They are generated from pre-existing relational tables. This is
sometimes referred to as a “bottom-up” approach. - They use database-generated primary key values for the ID
attribute. - They are part of a composition (or aggregation) of one or more other
JPA entity beans (for example, one-to-one or many-to-one
relationships).
You will learn how to construct an application that uses an Enterprise
JavaBean (EJB) 3.1 stateless session bean and a servlet at the Servlet 2.5
specification level to invoke a JPA transaction. Using JPA beans, you will
build a simple web application, Acme Membership, without writing much code.
Acme Gym Membership is a fictional health gym membership application to manage
members of the Acme Gym.
Before you
start
To follow along, you need to install the following:
- Eclipse IDE for Java EE Developers, Oxygen Release 4.7 development
environment with Java Development Kit (JDK) 8 Update 131 or later - Apache Derby Network Server V10.13.1.1
- Liberty Tools for Eclipse Oxygen
- IBM WebSphere Application Server Liberty 17.0.0.2 (targeting the Java
Enterprise Edition 7.0 specification)
Extract the resources.zip file from GitHub to a location of your choice in
your file system. It contains two files: members.sql and
AcmeMembershipApplication.ear. These resources include a script to create
your initial Derby database and an Enterprise Archive (EAR) file that
contains artifacts to begin developing your Java Enterprise Edition (JEE)
application.
The Acme Gym
membership scenario
To receive Acme’s gym services and benefits, clients must become members.
The membership_type field in the membership table identifies the type of
membership.
Clients can choose from single, student, or family
memberships. Family memberships provide Acme’s services to couples and any
children that they have who are under the age of 18.
All memberships will have, at most, one primary member. The primary member is
responsible for keeping the membership in good standing and for paying the
annual subscription fees. All correspondence between Acme and its members occurs solely
through the primary member. Acme collects the address and other contact
information for the primary member for all memberships for this purpose.
In addition to having a primary member, a family
membership normally has one or more dependents. There are two types
of dependents in a family membership: the spouse and any children younger
than 18.
To remain members in
“good standing,” clients must renew their memberships annually.
Figure 1 represents the relational database schema for Acme’s membership
subsystem.
Figure 1. The Acme membership data model
Import the
membership application
Now that you understand the scenario, let’s look at how to import the
membership application into your own environment.
- Launch Eclipse and open the web perspective.
- Import the initial WAR project that you will build upon:
- From the menu bar, select File >
Import. - Expand the Web folder, select WAR file and click
Next. - In the WAR Import wizard, click Browse,
navigate to the location where you downloaded and saved the
file AcmeMembershipApplicationWeb.war to and select it for
import. - Uncheck the Add project to an EAR and select
WebSphere Application Server Liberty for Target
runtime - Click Finish.
- From the menu bar, select File >
Upon successful import, you will see errors in the Markers view that you
can safely ignore for now. The new web project has a simple servlet that
uses a stateless session EJB to invoke the JPA entities you will create to
add members and memberships.
Create the
Acme membership database
Acme’s membership application depends on the existing layout of the Acme
database. You will recreate Acme’s membership database tables using the
Derby Network Server database.
- Open the Data Development perspective.
- In the Data Source Explorer view, right-click the Database Connections
folder and select New, and the New Connection Profile
wizard will appear. - Select Derby from the list of choices in the
Connection Profile Types panel and enterAcmeMembers
for
name. - Click Next.
- On the Specify a Driver and Connection Details page:
- Select the checkboxes next to Connect when the wizard completes and
Connect every time the workbench is
started . - Click the New Driver Definition icon, as shown below.
Figure 2. Configuring a new Derby
connection - The New Driver Definition wizard opens. In the name/type tab
of this wizard, select Derby Client JDBC driver with a
System Version of 10.2. - Click the JAR list tab and the derbyclient.jar entry in the
Driver files panel, then click the Edit
JAR/Zip button, as shown below.Figure 3. Linking the Derby library to
the new connection - Navigate to the installation direction of your local Derby
network server, and under the lib directory of your root Derby
installation, select the derbyclient.jar, indicating its
location, and click OK. - You are now back in the New Derby Connection Profile wizard.
On the Properties tab, enterACMEMEMBERS
for
database name. You can also optionally change the user ID and
password values from the defaults. Check the Create
database (if required), Upgrade database
to current version, and the Save
password checkboxes, as shown below. - Click Test Connection. Click
OK on the Ping Succeeded notification
pop-up dialog. - Click Finish.
Figure 4. Specifying database connection
details
- Select the checkboxes next to Connect when the wizard completes and
- Return to the web perspective and in the Enterprise Explorer view,
expand AcmeMembershipApplicationWeb > WebContent and open
Members.sql.- Select Derby_10.x from the type
drop-down list. - Select AcmeMembers from the name
drop-down list. - Select ACMEMEMBERS from the database
drop-down list.Figure 5. Preparing script to create Acme
membership database - Save the changes.
- Right-click anywhere in the open editor and select Execute
All. - The SQL Results view will open and show a success message.
- Select Derby_10.x from the type
If you
switch to the Data perspective and from the Data Source Explorer,
navigate to Database Connections > AcmeMembers >
ACMEMEMBERS > Schemas > ADMIN > Tables, you will
notice the creation of the new tables from executing the Members.sql
script.
Use the
identity value generation strategy
Having the database generate values for the primary key for a table (and by
extension, any foreign key values for related tables) eliminates the
burden from the application to do so. That is, not having to generate
unique key values for persistent objects within the application allows the
focus to remain on core business logic and business rules. This enhances the application’s maintainability and
readability.
In this scenario, Acme’s lead data and application architects
want to use the identity value generation approach to remove that burden
from the business logic of their various applications. To leverage that
capability, JPA can delegate assignment of an entity’s ID attribute to the
relational database. The primary key fields in the relational tables for
the ACMEMEMBERS database are set to generate unique values to adhere to
the identity value generation strategy.
Generate the
JPA entities
Now it’s time to generate the JPA entities from the ACMEMEMBERS database
tables. These JPA entities provide the foundation of the business logic
for Acme’s membership system. Switch to the web perspective and enable the
JPA facet for our web project.
- Right-click the AcmeMembershipApplicationWeb project and select
Properties. - Select Project Facets from the list of project
properties in the left-most pane. - In the list of available Project Facets in the center pane, select
JPA and ensure that the version is set to 2.1, as
shown below. - Click Further configuration available near the bottom
of the center pane.Figure 6. Enabling JPA for the
AcmeMembersWebApplication - In the JPA Facet dialog wizard:
- Select EclipseLink 2.5.x from the platform
drop-down list. - Select Library Provided by Target Runtime
from the type drop-down list. - Select AcmeMembers from the connection
drop-down list, as shown below. - Click OK.
- Click Apply and Close on the properties
dialog window.
Figure 7. Providing runtime details to enable
JPAAfter configuring your web project to support JPA, you can generate your
JPA entities: - Select EclipseLink 2.5.x from the platform
- Right-click the AcmeMembershipApplicationWeb project and select
JPA Tools > Generate Entities from
Tables. - On the Select Tables page of the Generate Custom Entities wizard:
- Select AcmeMembers from the connection
drop-down list. - Select ADMIN from the schema drop-down
list. - Be sure to check all tables listed in the tables list.
- Check the List generated classes in
persistence.xml checkbox. - Click Next.
- On the Table Associations page of the Generate Custom Entities
wizard, you have an opportunity to generate and shape
relationships between the entities you will
generate.- Select
the Dependent-Membership relationship and ensure both Cascade
fields are set to all, and enter membership
for the Property
field.In the screen shown below, you
are setting the name of the attribute that provides the
many-to-one relationship between the dependents in a family
and a family membership.Figure 8. Editing the relationships for
Dependent – Membership - Select the PrimaryMember-Membership
relationship and ensure the first Cascade field is set to
all. Enter primaryMember
for the Property field. Uncheck the last check box titled
“Generate a reference to a collection of MEMBERSHIP
in PRIMARYMEMBER”.Figure 9 shows setting the name of the attribute
that provides the aggregate relationship between the primary
member and that person’s membership with Acme.Figure 9. Editing the relationship for
PrimaryMember – Membership - Select the PrimaryMember-Address
relationship and ensure the first Cascade field is set to
all. Enter address for
the Property field. Uncheck the last check box titled
“Generate a reference to a collection of PRIMARYMEMBER in
ADDRESS”.Figure 10 shows setting the name of the attribute
that provides the aggregate relationship between the primary
member and that member’s residence address.Figure 10. Editing the relationship for
PrimaryMember – Address - Select the PrimaryMember-ContactInfo relationship and ensure
the first Cascade field is set to all.
Enter contactInfo for the Property field.
Uncheck the last box titled “Generate a reference to a
collection of PRIMARYMEMBER in CONTACTINFO”.Figure 11 shows setting the name of the attribute
that provides the aggregate relationship between the primary
member and that member’s contact information.Figure 11. Editing the relationship for
PrimaryMember – ContactInfo - Click Next.
- Select
- On the Customize Defaults page of the Generate Custom Entities wizard:
- Select Identity from the key generator drop-down list. Here, you are
indicating the desire to use the identity generation scheme as the
approach for generating unique values for primary key attributes for
your JPA domain classes.- Choose Property for the Entity Access radio
button. - Select java.util.Set for the Collections
Property Type radio button. - For the Package field, enter
org.acme.membership.domain
. - Click Next.
- Choose Property for the Entity Access radio
- On the Customize Individual Entities page of the Generate Custom
Entities wizard, you can customize numerous characteristics for both
the classes and their underlying attributes. Expand Dependent in the
tables and columns list box. Under Dependent, select the BIRTHDATE
column. In the corresponding Mapping type drop-down list, select
java.util.Calendar. - Repeat Step 4 for the BIRTHDATE column in PRIMARYMEMBER and for the
LASTRENEWALDATE and MEMBERSINCE columns in the MEMBERSHIP table. - Click Finish. Feel free to browse the generated JPA
entities in the AcmeMembershipApplicationDomain project.
- Select AcmeMembers from the connection
Adjust the JPA
entities
Before we can additional business logic, we need to adjust and enhance the JPA entities to
ensure that the entities reflect the business and application domain more
accurately. You will override the database interpretation of the
relationship of some of the entities to be one-to-one rather than
many-to-one. This will not affect the referential integrity or
primary-foreign key relationships between the tables in the membership
database. The reason for doing this is to make the application logic
reflect the business rules and constraints that exist between the entities
more closely.
Adjust Acme’s
JPA entities to one-to-one, unidirectional relationships
Assume that to reflect the constraints of the business rules for Acme’s
membership administration, you make a few adjustments to
your JPA entities:
- Tighten the cardinality (from many-to-one to one-to-one) for some of
the relationships. - Reduce the navigation flexibility for some of the relationships (from
bidirectional to unidirectional).
Both of these changes will make the
application more secure and less prone to breaking any of the business
rules for Acme’s membership application.
Change the cardinality of the
relationship.
- Switch to the JPA Eclipse perspective.
- Open the JPA Primarymember entity.
- In the JPA Structure view, select the address attribute.
- In the JPA Details view, select the many to one hyperlink, as shown
below.Figure 12. Changing the cardinality of the
relationship - In the Mapping Type Selection dialog window, select One to
One and click OK. - In the JPA Details view, uncheck the Optional
checkbox and check the All checkbox for the Cascade
options. - Repeat Steps 2-5 for these attributes:
- contactInfo in the
Primarymember JPA entity - primaryMember in the Membership JPA entity
- contactInfo in the
Important: Step 5 does not change the nature of the relationship of
your JPA entities. However, it is a necessary step for making a
complex object persistent (for example, an object composed of
collections and an aggregation of other complex objects).
Configure a
data source and JDBC driver for your WebSphere Liberty server
You will need to configure a JDBC driver and data source for your WebSphere
Liberty server to run the Acme Membership Web Application.
- In the Servers
view of the web perspective, expand the WebSphere Application Server
Liberty at localhost instance and double-click the Server Configuration
entry, as shown below.Figure 13. Opening the Liberty Server
Configuration - In the Design tab of the Server Configuration editor, select the root
Server Configuration entry and click
Add.Figure 14. Add a data source to the server
configuration - In the Add Element dialog, select Data Source and click
OK. - In the Design tab of the Data Source editor,
enterjdbc/AcmeMembers
for JNDI name and select
javax.sql.ConnectionPoolDataSource for type, as shown
below. Leave all other default values unchanged and save your editor.Figure 15. Configuring a new data source
- Still in the Data Source editor, click the Add button to
add one of the 18 child elements available. - In the Add Element dialog,
select Derby Network Client Properties and click
OK. - In the Derby Network Client Properties editor,
- select create for Create database and enter
AcmeMembers
for database name. - In the Advanced Properties
section, click the Set button next to the password
field. - In the Set Password dialog, enter a desired password, select
xor from the encoding drop-down list, and click
OK.
- select create for Create database and enter
- Save the Server Configuration editor.
- Select the
Data Source entry you added in the Server Configuration editor and click
Add. - In the Add Element dialog, select JDBC
Driver and click OK. - In the JDBC Driver
editor, click the Add button next to the Shared Library
element, as shown below.Figure 16. Configuring a new JDBC driver
- In the Add Element dialog, select Shared Library and click
OK - In the Shared Library editor, click the
Add button next to the Fileset, File, Folder
elements. - In the Add Element dialog, select Fileset and
click OK. - In the Fileset editor, for Base directory,
enter the location where the Derby library JAR files reside on your file
system, as shown below.Figure 17. Specifying the Derby library location
- Save the editor.
Run the Acme
membership application
You will finally run the Acme membership application on the WebSphere
Application Server Liberty environment. You will use a servlet to run the
Acme membership function to create a new family membership.
- In the Enterprise Explorer view, expand
AcmeMembershipApplicationWeb >
AcmeMembershipApplicationWeb > Servlets. - Right-click
org.acme.membership.admin.AddMembershipServlet
and select Run As > Run on Server.
After the WebSphere Liberty server starts, it will invoke your servlet and
open a web page, indicating success in creating a new membership. You can
inspect the Derby database tables to confirm the addition of the new
membership record.
Summary
For this tutorial, we used the Eclipse Oxygen release for Java EE
Developers to rapidly generate and customize JPA entities from a Derby
database that had tables that use the identity
value generation capability to create unique primary keys values and a
non-trivial set of relationships between the tables. The Eclipse
environment increased your productivity by using views and editors to help
you tailor your JPA entities, freeing you from hand-coding the required
annotations
you ran your application by using the WebSphere Liberty
Server to deploy and run the Acme Membership application.
Acknowledgement
The author thanks Hamid Kalantari for his thoughtful and thorough review of
this tutorial.
Downloadable resources
Related topics
Credit: IBM