LibraryToggle FramesPrintFeedback

JPA

Overview

To enable transactions in a JPA component, you need to provide the JPA component with a reference to a transaction manager, of JpaTransactionManager type. The Java Persistence API is a generic wrapper API for object-relational persistence and it can be layered over a variety of different object-relational mapping technologies.

Sample JPA configuration

Example 4 shows how to customize the configuration of a JPA component (creating a component with the bean ID, jpa), so that the JPA component supports Spring transactions. When used with transactions, the JPA component requires a reference to an entity manager factory and a reference to a transaction manager.

Example 4. JPA Transaction Manager Configuration

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="jpa" class="org.apache.camel.component.jpa.JpaComponent">
       <property name="entityManagerFactory" ref="entityManagerFactory"/>
       <property name="transactionManager" ref="jpaTxManager"/>
    </bean>

    <bean id="jpaTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="camel"/>
    </bean>

</beans>

JPA transaction manager bean

In Example 4, the jpaTxManager bean is a local JPA transaction manager instance, of JpaTransactionManager type. The JPA transaction manager requires a reference to an entity manager factory bean (in this example, the entityManagerFactory bean).

If you deploy your application into an OSGi container, however, you might want to consider using a JtaTransactionManager instead. See Table 2.

Entity manager factory bean

The entity manager factory bean encapsulates the JPA runtime functionality. For example, the Spring LocalEntityManagerFactoryBean class is just a wrapper around the standard javax.persistence.EntityManagerFactory class. The entity manager factory is used to create a javax.persistence.EntityManager instance, where the entity manager is associated with a unique persistence context. A persistence context represents a consistent set of entity objects that are instantiated from the underlying database (analogous to a Hibernate session).

The LocalEntityManagerFactoryBean class is a relatively simple JPA wrapper class that is suitable for simple demonstrations and testing purposes. This class reads its required configuration information from the persistence.xml file, which is found at the standard location, META-INF/persistence.xml, on the class path (see Sample persistence.xml file). The persistenceUnitName property references a section of the persistence.xml file.

JPA entity manager factories

As well as instantiating a LocalEntityManagerFactoryBean bean, there are other ways of obtaining a JPA entity manager factory, as summarized in Table 7.

Table 7. Obtaining JPA Entity Manager Factory

Entity Manager FactoryDescription
Obtain from JNDI If your application is deployed in a J2EE container, the recommended approach is to let the container take care of instantiating the entity manager factory. You can then obtain a reference to the entity manager factory using JNDI. See Obtaining an EntityManagerFactory from JNDI in the Spring documentation.
LocalEntityManagerFactoryBean For simple standalone applications and for testing, the simplest option is to create a bean of this type. The JPA runtime is configured using the standard META-INF/persistence.xml file.
LocalContainerEntityManagerFactoryBean Use this class, if you need to configure special bootstrap options for the JPA runtime. In spite of the name, this class is not restricted to containers; you can also use it in standalone mode. See LocalContainerEntityManagerFactoryBean in the Spring documentation.

JPA bootstrap contract

The JPA is a thin abstraction layer that allows you to write code that is independent of a particular object-relational mapping product—for example, it enables you to layer your application over products such as OpenJPA, Hibernate, or TopLink. To match the application code to a specific JPA implementation, JPA defines a bootstrap contract, which is a procedure to locate and configure JPA implementations, as follows:

  • To make a JPA implementation available to your application, put the JAR file containing the relevant JPA provider class (of javax.persistence.spi.PersistenceProvider type) on your class path. In fact, it is possible to add multiple JPA providers to your class path: you can optionally specify which JPA provider to use in the persistence.xml file.

  • The JPA persistence layer is configured by the standard persistence.xml file, which is normally located in META-INF/persistence.xml on the class path.

Sample persistence.xml file

Example 5 shows a sample persistence.xml file for configuring an OpenJPA JPA provider layered over a Derby database.

Example 5. Sample persistence.xml File

<?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="camel" transaction-type="RESOURCE_LOCAL">
    <!--
        The default provider can be OpenJPA, or some other product.
        This element is optional if OpenJPA is the only JPA provider
        in the current classloading environment, but can be specified
        in cases where there are multiple JPA implementations available.
    -->
    <provider> 1
      org.apache.openjpa.persistence.PersistenceProviderImpl
    </provider>

    <class>org.apache.camel.examples.MultiSteps</class> 2
    <class>org.apache.camel.examples.SendEmail</class>

    <properties> 3
      <property name="openjpa.ConnectionURL" value="jdbc:derby:target/derby;create=true"/>
      <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
      <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=TRACE"/>
    </properties>
  </persistence-unit>

</persistence>

1

The provider element can be used to specify the OpenJPA provider implementation class. If the provider element is omitted, the JPA layer simply uses the first JPA provider it can find. Hence, it is recommended to specify the provider element, if there are multiple JPA providers on your class path.

To make a JPA provider available to an application, simply add the provider's JAR file to the class path and the JPA layer will auto-detect the JPA provider.

2

Use the class elements to list all of the Java types that you want to persist using the JPA framework.

3

Use the properties element to configure the underlying JPA provider. In particular, you should at least provide enough information here to configure the connection to the underlying database.

Sample annotated class

The following code example shows how the org.apache.camel.examples.SendEmail class referenced in Example 5 should be annotated to turn it into a persistent entity bean (so that it is persistible by JPA):

// Java
package org.apache.camel.examples;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * Represents a task which is added to the database, then removed from the database when it is consumed
 *
 * @version $Revision$
 */
@Entity
public class SendEmail {
    private Long id;
    private String address;

    public SendEmail() {
    }

    public SendEmail(String address) {
        setAddress(address);
    }

    @Override
    public String toString() {
        return "SendEmail[id: " + getId() + " address: " + getAddress() + "]";
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

The preceding class has the following JPA annotations:

@javax.persistence.Entity

Specifies that the following class is persistible by the JPA.

@javax.persistence.Id

The following bean property must be used as the primary key (for locating objects of this type in the database).

@javax.persistence.GeneratedValue

Specifies that the primary key values should be automatically generated by the JPA runtime (you can optionally set attributes on this annotation to configure the ID generation algorithm as well).

For the complete list of JPA annotations, see the API for the javax.persistence package.

Comments powered by Disqus