Difference between revisions of "Gemini/JPA/Documentation/CreatingAnApplication"

From Eclipsepedia

Jump to: navigation, search
(Application Design)
(Application Design)
Line 60: Line 60:
 
#: A more reusable option is to package the persistence unit in a separate bundle and have the application code that needs to operate on the entities have a dependency on the persistence unit bundle or services it offers. <br/>
 
#: A more reusable option is to package the persistence unit in a separate bundle and have the application code that needs to operate on the entities have a dependency on the persistence unit bundle or services it offers. <br/>
 
# Nested Persistence Unit <br/><br/>
 
# Nested Persistence Unit <br/><br/>
#: A more advanced design is to nest a persistence unit JAR file inside the persistence bundle. While not common, it does allow a POJAR (Plain Old Java ARchive) containing a persistence unit to be easily incorporated into a bundle. The JAR must be placed on the bundle classpath, and the persistence descriptor must be qualified in the ''Meta-Persistence'' header using the embedded JAR syntax. For example, if a JAR named ''empUnit.jar'' contained a ''jpa.xml'' persistence descriptor in the ''META-INF'' folder, and the ''empUnit.jar'' file was placed in the ''jpa'' folder of the ''appBundle.jar'' application bundle, as shown in the following diagram:
+
#: A more advanced design is to nest a persistence unit JAR file inside the persistence bundle. While not common, it does allow a POJAR (Plain Old Java ARchive) containing a persistence unit to be easily incorporated into a bundle. The JAR must be placed on the bundle classpath, and the persistence descriptor must be qualified in the ''Meta-Persistence'' header using the embedded JAR syntax. For example, if a JAR named ''empUnit.jar'' contained a ''jpa.xml'' persistence descriptor in the ''META-INF'' folder, and the ''empUnit.jar'' file was placed in the ''jpa'' folder of the ''appBundle.jar'' application bundle, as shown in the following hierarchy:
 
+
  
 +
  appBundle.jar
 +
    jpa/
 +
      empUnit.jar
 +
        META-INF/
 +
          jpa.xml
  
 
then the ''MANIFEST.MF'' file in the application bundle would include the following headers:
 
then the ''MANIFEST.MF'' file in the application bundle would include the following headers:

Revision as of 11:41, 13 September 2012

Contents

Creating a Persistence Application

The following sections describe how to create and configure a JPA application using Gemini JPA.

Defining a Persistence Unit

When defining a persistence unit there are a few differences when using Gemini JPA in OSGi, as opposed to traditional JPA in a classpath-based environment. Traditional JPA dictates that a persistence descriptor called persistence.xml file must be placed in the META-INF folder of a JAR file. In OSGi, the limitations are not as stringent and the file may be given any name and placed anywhere in the persistence bundle, the bundle containing the persistence unit. The caveat is that a special manifest header, the Meta-Persistence header, must be added to the META-INF/MANIFEST.MF file and the named descriptor, with its location relative to the root of the bundle, indicated as the value of the header. Multiple descriptors may even be specified defining multiple persistence units. If the traditional META-INF/persistence.xml descriptor name and location is used then the Meta-Persistence header entry can be left with an empty value entry. The default descriptor, if it exists, is always added to the set of descriptors that are specified in the Meta-Persistence headers. The following are examples of valid Meta-Persistence entries:

  • Meta-Persistence: META-INF/persistence.xml
    Uses the default descriptor and (redundantly) indicates the name and location.
  • Meta-Persistence:
    Assumes the default META-INF/persistence.xml descriptor. Note that one or more spaces may need to be used as the value to satisfy the manifest parser.
  • Meta-Persistence: META-INF/jpa.xml
    Specifies a file named jpa.xml located in the META-INF folder of the bundle. If META-INF/persistence.xml exists in the bundle then the persistence units defined in it will also be processed.
  • Meta-Persistence: jpa1.xml, jpa2.xml
    Specifies two persistence descriptors, jpa1.xml and jpa2.xml, both located in the root of the bundle. If META-INF/persistence.xml exists in the bundle then the persistence units defined in it will also be processed.

Persistence Descriptor

The contents of the persistence descriptor for the most part follows the typical contents of a standard persistence.xml file in a Java SE environment. The following stipulations and rules also apply:

  1. The transaction type should be RESOURCE_LOCAL (if specified).
  2. If the mapping-file element is used the entry must be relative to the root of the bundle.
  3. Entities should be enumerated in class elements.
  4. The javax.persistence.jdbc.{driver,url,user,password} properties must be used to specify the JDBC connection properties.

In addition, EclipseLink-specific properties an be used as described in the EclipseLink documentation.

Declaring your Dependencies

As when using OSGi for any application, the dependencies that you specify in your persistence application must be carefully defined and properly specified. The first thing you must declare is a dependency on the set of JPA 2.0 javax.persistence packages that you use. (Note: Even if you are creating a persistence bundle with no annotations and using XML for all of the mapping you must import the javax.persistence package.)

When importing the JPA packages, the OSGi standard recommends that the “jpa” attribute be set to “2.0” to indicate the 2.0 version of the JPA specification. The EclipseLink javax.persistence jar does the exporting using this attribute. An example application import is:

Import-Package: javax.persistence;jpa=”2.0”;version=”1.1.0”, …

If EclipseLink API’s are used then additional EclipseLink package dependencies may also be required.

JDBC Access

There are two ways of getting to the JDBC driver. Gemini DBAccess can be used for shared driver access, or a JDBC driver can be included in the bundle for localized access.

Using Gemini DBAccess

Gemini DBAccess offers modular sharable JDBC driver access to selected database drivers. By installing and starting the DBAccess support bundle, as well as the database driver bundle(s), Gemini JPA can be a consumer of the DataSourceFactory service defined by the OSGi JDBC specification.

DBAccess posts a DataSourceFactory service for the JDBC driver using the JDBC driver class name as the service name. When JPA needs a datasource it takes the driver class specified in the javax.persistence.jdbc.driver property and uses it to look up the datasource factory. Once it finds the factory it creates a datasource and holds onto it to obtain connections when required.

Using a local JDBC Driver

If DBAccess is not used then the JDBC driver should be made accessible to Gemini JPA when it processes the persistence unit. The best way to do this is to package the driver in the persistence unit bundle, ensuring it is on the Bundle-ClassPath as well.

Application Design

The structure of a persistence application is fairly constrained according to the OSGi JPA specification, and falls into one of the following three architectural options:

  1. Inlined Persistence Unit
    A common and simple application design is one that makes use of a JPA persistence unit that is co-resident (in the same bundle) with the application code that invokes it. In this design the application is packaged up into a single bundle, including both the persistence entities and the code that operates on them.
  2. Modular Persistence Unit
    A more reusable option is to package the persistence unit in a separate bundle and have the application code that needs to operate on the entities have a dependency on the persistence unit bundle or services it offers.
  3. Nested Persistence Unit

    A more advanced design is to nest a persistence unit JAR file inside the persistence bundle. While not common, it does allow a POJAR (Plain Old Java ARchive) containing a persistence unit to be easily incorporated into a bundle. The JAR must be placed on the bundle classpath, and the persistence descriptor must be qualified in the Meta-Persistence header using the embedded JAR syntax. For example, if a JAR named empUnit.jar contained a jpa.xml persistence descriptor in the META-INF folder, and the empUnit.jar file was placed in the jpa folder of the appBundle.jar application bundle, as shown in the following hierarchy:
 appBundle.jar
   jpa/
     empUnit.jar
       META-INF/
         jpa.xml

then the MANIFEST.MF file in the application bundle would include the following headers:

Meta-Persistence: jpa/empUnit.jar!/META-INF/jpa.xml
...
Bundle-ClassPath: ., jpa/empUnit.jar