Prepare and package persistence applications to test outside
of the application server container in a Java SE environment.
About this task
JPA applications require different configuration techniques
from applications that use container-managed persistence (CMP) or
bean-managed persistence (BMP). They do not follow the typical deployment
techniques that are associated with applications that implement CMP
or BMP. In JPA applications, you must define a persistence unit and
configure the appropriate properties in the persistence.xml file to
ensure that the applications can run in a Java SE environment.
There
are some considerations for running JPA applications in a Java SE
environment:
- Resource injection is not available. You must configure these
services specifically or programmatically.
- The life cycle of the EntityManagerFactory and EntityManager are
managed by the application. Applications control the creation, manipulation,
and deletion of these constructs programmatically.
For this task, you need to specify the com.ibm.ws.jpa.client_6.1.0.jar
standalone JAR file and j2ee.jar file in your classpath. This standalone
JAR file is available from the client install images. The location
of this file on the client install image is app_client_root.
The j2ee.jar file is located in the directory lib/j2ee.jar.
Procedure
- Generate your entities classes. Depending
upon your development model, you might use some or all of the JPA tools:
- Top-down mapping: You start from scratch with the entity definitions
and the object-relational mappings, and then you derive the database schemas
from that data. If you use this approach, you are most likely concerned with
creating the architecture of your object model and then writing your entity
classes. These entity classes would eventually drive the creation of your
database model. If you are using a top-down mapping of the object model to
the relational model, develop the entity classes, and then use OpenJPA functionality
to generate the database tables that are based on the entity classes. The
wsmapping tool would help with this approach.
- Bottom-up mapping: You start with your data model, which are the
database schemas, and then you work upwards to your entity classes. The wsreversemapping
tool would help with this approach.
- Meet in the middle mapping: probably the most common development
model. You have a combination of the data model and the object model partially
complete. Depending on the goals and requirements, you will need to negotiate
the relationships to resolve any differences. Both the wsmapping tool and
the wsreversemapping tool would help with this approach.
The JPA solution for the application server provides several tools that
help with developing JPA applications. Combining these tools with the Eclipse
Dali plugin provides a solid development environment for either Java EE or
Jave SE applications. The Eclipse Dali project provides a plugin that includes
GUI tools to insert annotations, a customized persistence.xml file editor,
a database explorer, and other features. More information on the Dali plugin
can be found at the Eclipse Dali web site.
- Optional: Enhance the entity classes using
the JPA enhancer tool, or specify the Java agent to perform dynamic
enhancement at run time.
- Optional: If you are not using the development
model for bottom-up mapping, generate or update your database tables automatically
or by using the wsmapping tool.
Refer to the section on runtime forward mapping in the Apache OpenJPA
User's Guide for more information.
- Optional: If you are using application-managed
identity, generate an application-managed identity class with the
wsappid tool. When you use an application-managed identity,
one or more of the fields must be an identity field. Use an identity
class if your entity has multiple identity fields and at least one
of the fields is related to another entity. The application-managed
identity tool generates Java code that uses the identity class for
any persistent type that implements application-managed identity.
For example, type the following at a prompt:
- Configure the properties of the persistence unit in the
persistence.xml file that will be used in the JPA application.
- Specify your data source. Use the openjpa.Connection
property to obtain a connection to the database. When you run a JPA
application in a Java SE environment, a JTA data source will be treated
as a data source that is not JTA compliant.
- Select com.ibm.websphere.persistence.PersistenceProviderImpl
as the persistence provider.
Avoid trouble: Include
the persistence provider in the classpath if you run the JPA application
as a standalone application.
gotcha
- Specify your database configuration options. Indicate
the database type and method of connection in the persistence.xml
file.
<property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="openjpa.ConnectionURL" value="jdbc:derby:target/database/jpa-test-database;create=true"/>
- Specify the transaction type to RESOURCE_LOCAL.
For example, the following entry should be in the persistence.xml
file:
<persistence-unit name="persistence_unit" transaction-type="RESOURCE_LOCAL">
- Include the location of the object relationship mapping
file, orm.xml, and any additional mapping files. For
example, the following entry should be in the persistence.xml file:
<mapping-file>META-INF/JPAorm.xml</mapping-file>
- Add any vendor specific properties to the persistence
unit.
- Package the application.
Note: Package
the persistence units in separate JAR files to make them more accessible
and reusable. If you package the persistence units this way, they
can be tested outside the container, both with and without the occurrence
of database persistence. The persistence units can be included in
standalone applications, or they can be packaged into EAR files as
persistence archive files. If you package the persistence unit into
a persistence archive file, all of the application components must
be able to access the persistence archive. The application that uses
the persistence units must declare a dependency on the persistence
archive using the MANIFEST.MF Class-Path: declaration.
To package the application:jar -cvf ${jar_Name} ${entity_Path}
where
${jar_Name} represents the name of the JAR file
to create, and ${entityPath} represents the root
location where the entities reside, which is where you compiled them.
- When you run your standalone application, specify the com.ibm.ws.jpa.client_6.1.0.jar
standalone JAR file and j2ee.jar file in your classpath when executing
your application. The stand-alone JAR file is available
from the client install image. The j2ee.jar file is located in the
lib/j2ee.jar directory. For example, use the following
Java call to run the com.xyz.Main standalone application:
java -classpath
${app_client_root}/runtimes/com.ibm.ws.jpa.client_6.1.0.jar:${app_client_root}/lib/j2ee.jar:other_jar_file.jar com.xyz.Main
Example
The following is a sample persistence.xml file for the Java
SE environment:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="TheWildZooPU" transaction-type="RESOURCE_LOCAL">
<jta-data-source>jdbc/FooBarDataSourceJNDI</jta-data-source>
<!-- additional Mapping file, in addition to orm.xml>
<mapping-file>META-INF/JPAorm.xml</mapping-file>
<class>com.company.bean.jpa.PersistebleObjectImpl</class>
<class>com.company.bean.jpa.Animal</class>
<class>com.company.bean.jpa.Dog</class>
<class>com.company.bean.jpa.Cat</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="openjpa.Log" value="DefaultLevel=INFO,SQL=TRACE,File=./dist/jpaEnhancerLog.log,Runtime=INFO,Tool=INFO"/>
<property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, PrettyPrintLineLength=72"/>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
</properties>
</persistence-unit>
</persistence>