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.

Configuring the Local Oracle Database in GlassFish

First, you much configure GlassFish to access the local Oracle server.

Exercise 12.1

Configure a GlassFish JDBC connection pool to connect to Oracle as follows.

  1. 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.

  2. 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.

  3. 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.

  1. Compare and contrast the database connection you built in Guide 12 (in Intellij IDEA) and this database connection (in GlassFish). Do we need both? If so, explain why; if not, explain why not.

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.

Building JPA Entity Classes

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.

Exercise 12.2

Configure a JPA persistence unit for your application as follows.

  1. 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.
      • URL: jdbc:oracle:thin:@localhost:1521:XE
      • Driver: oracle.jdbc.OracleDriver
      • the standard CPDB username and password.
  2. In the persistence pane, generate a JPA mapping for the CPDB Person, Household, PersonTeam and Team tables.

    1. Click mouse-right on the cpdbEntities persistence unit and choose Generate Persistence Mapping→By Database Schema.
    2. Set the database source to your CPDB database source.
    3. Create a new package/directory for the entities called models.
    4. Select the Person, Household, PersonTeam and Team tables (only). Open each of the tables in the mapping wizard and ensure that only the basic fields are selected; for now, don’t select any of Intellij’s inferred relationships or any of the foreign keys (e.g., Person.householdId).

    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.

  1. How does Intellij map the database tables into Java entity classes?
  2. What is the PK class do?
  3. Does Intellij default to field or property annotations?

You’ll try out the Person entity first, and then move on to the relationships.

Marshalling Entities from a Single Entity Class

EclipseLink/Moxy provides automatic marshalling of JPA entities to (and from) JSON.

Exercise 12.3

Add the following application code to the src/ directory.

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.

Verify that the service implements the given URLs and then add answers to the following questions to notes.txt.

  1. Does this application perform marshalling? If so, explain what the marshalling does; if not, explain why it’s not needed.
  2. Does this code perform any injection? Again, explain…
  3. What does the entity manager do in this code, if anything?

It would not be difficult to add GET/Read support for the other entity classes.

Marshalling Inter-Entity-Class Relationships

JPA also supports relationships between tables. We’ll focus our access support on the Person table and its relationships with the other tables.

Exercise 12.4

Add annotations to your Person entity class to support the following relationships.

Add answers to the following questions to notes.txt.

  1. How does JPA return the household and team entities related to a given person?

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.

Exercise 12.5 [Homework]

Add the following PUT/POST/DELETE resources for the Person table that respond to the following URLs.

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.

Checking in

We will grade your work according to the following criteria: