17 Testing JPA Outside a Container

This chapter describes how, with Oracle TopLink, you can use the persistence unit JAR file to test your application outside the container (for instance, in applications for the Java Platform, Standard Edition (Java SE platform)).

This chapter includes the following sections:

Use Case

Users need to use TopLink both inside and outside the container (such as applications for the Java SE platform).

Solution

This solution highlights the primary differences when using TopLink outside a container.

Components

  • TopLink 12c (12.1.2.0.0) or later.

    Note:

    TopLink's core functionality is provided by EclipseLink, the open source persistence framework from the Eclipse Foundation. EclipseLink implements Java Persistence API (JPA), Java Architecture for XML Binding (JAXB), and other standards-based persistence technologies, plus extensions to those standards. TopLink includes all of EclipseLink, plus additional functionality from Oracle.
  • An application server (such as Oracle WebLogic Server, IBM WebSphere, or Glassfish)

17.1 Understanding JPA Deployment

When deploying outside of a container, use the createEntityManagerFactory method of the javax.persistence.Persistence class to create an entity manager factory. This method accepts a Map of properties and the name of the persistence unit. The properties that you pass to this method are combined with those specified in the persistence.xml file. They may be additional properties or they may override the value of a property that you specified previously in the persistence.xml file.

Tip:

This is a convenient way to set properties obtained from program input, such as the command line.

17.1.1 Using EntityManager

The EntityManager is the access point for persisting an entity bean, loading it from the database. Usually, the Java Persistence API (JPA) container manages interaction with the data source. However, if you are using a JTA data source for your JPA persistence unit, you can access the JDBC connection from the Java EE program container's data source. Because the managed data source is unavailable, you can pass properties to createEntityManagerFactory to change the transaction type from JTA to RESOURCE_LOCAL and to define JDBC connection information, as shown here:

Example 17-1 Changing transaction type and defining connection information

import static org.eclipse.persistence.jpa.config.PersistenceUnitProperties.*;
 
...
 
Map properties = new HashMap();
 
// Ensure RESOURCE_LOCAL transactions is used.
properties.put(TRANSACTION_TYPE,
  PersistenceUnitTransactionType.RESOURCE_LOCAL.name());
 
// Configure the internal EclipseLink connection pool
properties.put(JDBC_DRIVER, "oracle.jdbc.OracleDriver");
properties.put(JDBC_URL, "jdbc:oracle:thin:@localhost:1521:ORCL");
properties.put(JDBC_USER, "user-name");
properties.put(JDBC_PASSWORD, "password");
properties.put(JDBC_READ_CONNECTIONS_MIN, "1");
properties.put(JDBC_WRITE_CONNECTIONS_MIN, "1");
 
// Configure logging. FINE ensures all SQL is shown
properties.put(LOGGING_LEVEL, "FINE");
 
// Ensure that no server-platform is configured
properties.put(TARGET_SERVER, TargetServer.None);

You also have access to the EclipseLink extensions to the EntityManager.

17.2 Configuring the persistence.xml File

The persistence.xml file is the deployment descriptor file for persistence using JPA. It specifies the persistence units and declares the managed persistence classes, the object/relation mapping, and the database connection details.

17.2.1 Main Tasks

To configure the persistence.xml file, the following tasks:

17.2.1.1 Task 1: Use the persistence.xml File

Example 17-2 illustrates a persistence.xml file for a Java SE platform configuration (that is, outside a container).

Example 17-2 A persistence.xml File Specifying the Java SE Platform Configuration

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd" version="1.0">
    <persistence-unit name="my-app" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
            <property name="javax.persistence.jdbc.user" value="scott"/>
            <property name="javax.persistence.jdbc.password" value="tiger"/>
        </properties>
    </persistence-unit>
</persistence>

17.2.1.2 Task 2: Instantiate EntityManagerFactory

An EntityManagerFactory provides an efficient way to construct EntityManager instances for a database. You can instantiate the EntityManagerFactory for the application (illustrated in Example 17-2) by using:

Persistence.createEntityManagerFactory("my-app");

17.3 Using a Property Map

You can use a property map to override the default persistence properties and use container deployment.

17.3.1 Main Tasks

To use a property map, perform the following steps:

17.3.1.1 Task 1: Configure the persistence.xml File

Example 17-3 illustrates a persistence.xml file that uses container deployment.

Example 17-3 A persistence.xml File Specifying the Java SE Platform Configuration, for use with a Property Map

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd" version="1.0">
    <persistence-unit name="employee" transaction-type="RESOURCE_LOCAL">
        <non-jta-data-source>jdbc/MyDS</non-jta-data-source>
    </persistence-unit>
</persistence>

Note:

There is no data source available when tested outside a container.

17.3.1.2 Task 2: Configure the Bootstrapping API

To test the persistence unit shown in Example 17-3 outside the container, you must use the Java SE platform bootstrapping API. Example 17-4 contains sample code that illustrates this bootstrapping.

Example 17-4 Sample Configuration

import static org.eclipse.persistence.config.PersistenceUnitProperties.*;

...

  Map properties = new HashMap();

  // Ensure RESOURCE_LOCAL transactions is used.
  properties.put(TRANSACTION_TYPE,
    PersistenceUnitTransactionType.RESOURCE_LOCAL.name());

  // Configure the internal connection pool
  properties.put(JDBC_DRIVER, "oracle.jdbc.OracleDriver");
  properties.put(JDBC_URL, "jdbc:oracle:thin:@localhost:1521:ORCL");
  properties.put(JDBC_USER, "scott");
  properties.put(JDBC_PASSWORD, "tiger");

  // Configure logging. FINE ensures all SQL is shown
  properties.put(LOGGING_LEVEL, "FINE");
  properties.put(LOGGING_TIMESTAMP, "false");
  properties.put(LOGGING_THREAD, "false");
  properties.put(LOGGING_SESSION, "false");

  // Ensure that no server-platform is configured
  properties.put(TARGET_SERVER, TargetServer.None);

17.3.1.3 Task 3: Instantiate the EntityManagerFactory

An EntityManagerFactory provides an efficient way to construct EntityManager instances for a database. You can instantiate the EntityManagerFactory for the application (illustrated in Example 17-4) by using:

Persistence.
createEntityManagerFactory("unitName", "properties");

17.4 Using Weaving

Weaving is a technique of manipulating the byte-code of compiled Java classes.

EclipseLink uses weaving to enhance Plain Old Java Object (POJO) classes and JPA entities with many features such lazy loading, change tracking, fetch groups, and internal optimizations.

17.4.1 How to Disable or Enable Weaving in a Java SE Environment

In a Java SE environment weaving is not enabled by default. This can affect LAZY One-To-One, Many-To-One and Basic relationships. It also has a major effect on performance and disable attribute change tracking.

To enable weaving in Java SE, the EclipseLink agent must be used when starting the Java VM.

java -javaagent:eclipselink.jar

Spring could also be used to allow JPA weaving in Java SE. See http://wiki.eclipse.org/EclipseLink/Examples/JPA/JPASpring for more information.

Static weaving can also be used, by including the following persistence property,

<property name="eclipselink.weaving" value="static"/>

See "weaving" in Java Persistence API (JPA) Extensions Reference for Oracle TopLink for more information.

17.4.2 How to Disable or Enable Weaving in a Java EE Environment

In a Java EE environment weaving is enabled by default (on any Java EE 5 or greater fully compliant application server, such as Weblogic, Webspehere, and Glassfish. JBoss does not allow weaving so you must use static weaving or Spring).

To disable weaving the weaving persistence unit property can be used,

<property name="eclipselink.weaving" value="false">
 

For more information on weaving see "weaving" in Java Persistence API (JPA) Extensions Reference for Oracle TopLink.

17.5 Additional Resources

For additional information about JPA deployment, see the following sections of the JPA Specification (http://jcp.org/en/jsr/detail?id=317):

  • Section 7.2, "Bootstrapping in Java SE Environments"

  • Chapter 7, "Container and Provider Contracts for Deployment and Bootstrapping"

17.5.1 Related Javadoc

For more information, see the following APIs in Java API Reference for Oracle TopLink:

  • PersistenceUnitProperties class

  • EntityManagerFactory interface

  • JpaEntityManager interface