For this lab, you will continue working on the Intellij IDEA project you built in the guide. As in the guide, this exercise assumes that you’ve configured a database connection for the Oracle CPDB.
First, you much configure GlassFish to access the local Oracle server.
Configure a GlassFish JDBC connection pool to connect to Oracle as follows.
Start your lab application on a local GlassFish server. The application won’t
do much yet, but this will start the GlassFish server. You could also start the server
using start-domain
as described in the previous lab.
Open localhost:4848 (the GlassFish admin tool), go to Resources→JDBC→JDBC Connection Pools and create a new connection pool with these settings:
Pool Name: OraclePool Resource Type: javax.sql.DataSource Database Driver Vendor: Oracle
and these “Additional Properties”:
url: jdbc:oracle:thin:@localhost:1521:XE
Note that you can use this admin tool to control the GlassFish server and to debug applications (see Applications for a list of deployed applications and Monitoring Data for server logs.
Set this (new) JDBC resource as the default connection pool by choosing Resources→JDBC→JDBC Resources→jdbc/__default and setting “Pool Name” to OraclePool (rather than DerbyPool).
When your application requests a JDBC connection, GlassFish will now automatically provide this new connection pool. For details on this process, see JDBC Connection Pools in Glassfish.
Save answers to the following questions in a notes.txt
file in the root of your
project.
This pool will be available anytime GlassFish is run, either locally or globally. In the lab, you may need to rebuild this connection each time the machine reboots.
You can now build a set of annotated POJOs to serve as JPA entity classes and group them in a persistence unit. It is easiest to allow Intellij create these for you based on the CPDB schema.
Configure a JPA persistence unit for your application as follows.
Modify the persistence unit in src/META-INF/persistence.xml
as follows.
persistence-unit
tags — Set an appropriate unit name and add
JTA transation support as follows.
<persistence-unit name="cpdbEntities"
transaction-type="JTA">
properties
— Set the persistence unit properties as follows.
jdbc:oracle:thin:@localhost:1521:XE
oracle.jdbc.OracleDriver
In the persistence pane, generate a JPA mapping for the CPDB Person, Household, PersonTeam and Team tables.
models
.This will create a new entity classes in models/*.java
. You may need to re-enter the DB
username and password in persistence.xml
, so check on that.
You can run the application now, but it will only present a default webpage. Add answers to
the following questions to notes.txt
.
PK
class do?You’ll try out the Person entity first, and then move on to the relationships.
EclipseLink/Moxy provides automatic marshalling of JPA entities to (and from) JSON.
Add the following application code to the src/
directory.
CPDBResource.java
class based on this sample code, asking IDEA to import the required libraries (using
alt-enter).
MyApplication.java
code from your lab
11 solution, modifying the resource class to the name of your new CPDB resource class.
Then build a run configuration for the app and verify that it works. The application should implement a RESTful service that responds to the following URLs.
cpdb/hello
— a simple hello-world messagecpdb/person/x
— a JSON-formatted version of the
person record with ID xcpdb/people
— a JSON-formatted list of all the person records.Verify that the service implements the given URLs and then add answers to the following questions to notes.txt
.
It would not be difficult to add GET/Read support for the other entity classes.
JPA also supports relationships between tables. We’ll focus our access support on the Person table and its relationships with the other tables.
Add annotations to your Person entity class to support the following relationships.
ManyToOne — Add a new field of type Household to the Person entity
class, add the accessor methods (getName()
&
setName()
) and annotate its get accessor as follows.
@ManyToOne @JoinColumn(name = "HOUSEHOLDID", referencedColumnName = "ID")
Run the application again and verify that the appropriate household entity now appears in the marshalled Person entity that is returned.
ManyToMany — Add a new list of Team entities to the Person entity class, add the accessor methods for this list attribute and annotate its get accessor as follows.
@ManyToMany @JoinTable(name = "PERSONTEAM", schema = "CPDB", joinColumns = @JoinColumn(name = "PERSONID", referencedColumnName = "ID", nullable = false), inverseJoinColumns = @JoinColumn(name = "TEAMNAME", referencedColumnName = "NAME", nullable = false))
Run the application again and verify that the appropriate team entities now appear in the marshalled Person entity that is returned.
Add answers to the following questions to notes.txt
.
See the details on JPA support for these and other relationships in Java Persistence/Relationships.
With the GET/read support in place, we can now add support for the other CRUD operations (i.e., PUT/update, POST/create & DELETE support). Intellij IDEA provides a wizard for creating JPA relationship annotations, see JPA and Hibernate, but the tutorials are based on Hibernate and the wizard is perhaps more difficult to understand than simply coding the raw annotations; we’ll opt for the latter.
Add the following PUT/POST/DELETE resources for the Person table that respond to the following URLs.
PUT cpdb/person/x
— Modify the given person
entity, it it exists, using the values in the JSON-formatted person entity passed with
the request.
POST cpdb/people
— Add the person entity passed with the request
to the database, allowing the CPDB sequence to assign a new, unique ID number, and
linking the person to the existing household with the ID given in the passed person
entity. You may assume that the household record with the given ID exists. Note that passing in the ID
may require that you add a transient field for the householdId foreign key.
DELETE cpdb/person/x
— Delete the person entity
with the given ID, it it exists.
Your RESTful service should now include GET/PUT/POST/DELETE for Person records and their associated Household. No other tables or relationships are required to be supported (e.g., Teams). Though not required for this homework, it would be good review which of these commands are idempotent and which are not.
Note you will need to configure the Oracle sequence used to assign Person IDs by adding the following annotations to the Person.Id.
@GeneratedValue(generator = "cpdbSequence") @SequenceGenerator(name = "cpdbSequence", sequenceName = "cpdb_sequence", allocationSize = 1)
The JPA entity manager supports the following API methods.
em.find(EntityClassName.class, id)
Find the person entity with the specified ID.
em.createQuery(em.getCriteriaBuilder().createQuery(EntityClassName.class)).getResultList()
Find all EntityClassName (e.g., person) entities and return them as a
List<EntityClassName>
.em.persist(EntityName)
Add the given object to the database.
em.merge(EntityName)
Modify the given entity in the database, returning the new entity.
em.remove(EntityName)
Deletes the given entity from the database.
For details, see Java Persistence/Persisting.
We will grade your work according to the following criteria: