JPA Applications

The Java Persistence API (JPA) is a new programming model under the EJB3.0 specification for the management of persistence and object or relational mapping with Java EE and Java SE. With JPA, you can easily develop java applications that perform operations on an RDBMS by using java objects and mapping. In that way, java applications developed using JPA are not only portable across different platforms, but applications can also be easily developed by using simple yet powerful programming models that are provided by JPA. JPA insulates applications from all of the complexity and non-portable boilerplate code involved in database connectivity and operations. Geronimo integrates OpenJPA as the JPA provider for applications deployed in Geronimo.

The schema diagram of persistence_1_0.xsd is shown in the following figure:

A persistence unit is defined by using the persistence-unit element. Child elements of a persistence-unit are given below:

  • description: A description of the persistence unit.

  • provider: The fully-qualified name of a provider class that supplies instances of EntityManager for this persistence unit.

  • jta-data-source: Container-specific name of the JTA DataSource to use.

  • non-jta-data-source: Container-specific name of the non-JTA DataSource to use.

  • mapping-file: File containing the mapping information.

  • jar-file: JAR file that should be scanned for entities.

  • class: Class to scan for annotations.

  • exclude-unlisted-classes: When this value is set to true, only the listed JARs and classes will be scanned for persistent classes. Otherwise, the enclosing JAR or directory will also be scanned.

  • properties: A list of vendor-specific properties as name/value pairs, specified as attributes in a property element.

The persistence.xml file is located under the META-INF directory of the EJB JAR file.

Annotations

In this section, we will look at some annotations used in Container Managed Persistence (CMP) and Bean Managed Persistence (BMP) bean classes using JPA.

  • Entity: The @Entity annotation is used on a POJO class that has at least one field or getter method that is annotated with the @Id annotation.

  • Id: The @Id annotation is used to annotate the field or getter method that specifies the primary key of the entity.

  • Table: The @Table annotation is used to specify the database table to which the entity bean will be mapped.

  • Column: The @Column annotation is used to specify the column to which the property is mapped.

  • GeneratedValue: The @GeneratedValue annotation is used to indicate that the container or the database will generate a value when a new entity instance is created.

  • PersistenceContext: The @PersistenceContext annotation is used to specify a dependency on a container-managed EntityManager persistence context.

  • PersistenceUnit: The @PersistenceUnit annotation is used to specify a dependency on an EntityManagerFactory. This annotation gives more control over the lifecycle of the EntityManager than the @PersistenceContext annotation does, in that the application, rather than the container, can create and destroy EntityManager instances.

Container-managed persistence

The use of @PersistenceContext on an EntityManager field results in an instance of a container-managed EntityManager being injected by the container. The EntityManager's persistent context propagates along with any active transactions; therefore, all references to EntityManager corresponding to the same persistence unit will have the same persistence context throughout the transaction. The lifecycle of the entity manager and the corresponding persistence context is managed by the container.

CMP sample application

The sample library application demonstrating Container Managed Persistence contains two entity classes, namely, Member and Book, along with a stateless session bean named LibraryBean. The session bean implementation class is shown below:

@Stateless
public class LibraryBean implements Library {
@PersistenceContext(type=PersistenceContextType.TRANSACTION)
private EntityManager em;
public void addBook(String name, String author) {
Book book = new Book();
book.setBookId((int)System.nanoTime());
book.setName(name);
book.setAuthor(author);
em.persist(book);
}
...
}

Notice that the EntityManager will be injected by the container into the session bean field em. The default persistence scope of a container-managed EntityManager is TRANSACTION, and the transaction-type is JTA. The persistence.xml file for this application is as given below:

<?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="MembersUnit" transaction-type="JTA">
<description>CMP w JPA</description>
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl </provider>
<jta-data-source>LibraryDS</jta-data-source>
<class>sample.jpa.Member</class>
<class>sample.jpa.Book</class>
</persistence-unit>
</persistence>

Notice that the two entity classes —Member and Book—associated with the persistence unit MembersUnit.

The deployment plan openejb-jar.xml is as given below:

<?xml version="1.0" encoding="UTF-8"?>
<openejb-jar xmlns="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.2">
<sys:environment>
<sys:moduleId>
<sys:groupId>packt.samples</sys:groupId>
<sys:artifactId>cmp-jpa-ejb</sys:artifactId>
<sys:version>1.0</sys:version>
<sys:type>jar</sys:type>
</sys:moduleId>
<dependencies>
<dependency>
<groupId>console.dbpool</groupId>
<artifactId>LibraryDS</artifactId>
<type>rar</type>
</dependency>
</dependencies>
</sys:environment>
<enterprise-beans/>
</openejb-jar>

Notice that the deployment plan defines a dependency on the database pool LibraryDS.

To run the sample application, we first need to create a database and a database pool. In order to do so, create a database with the name LIBRARYDB by using the DB Manager portlet. Then deploy the database pool by using <GERONIMO_HOME> epositoryorg ranql ranql-connector-derby-embed-local1.4 ranql-connector-derby-embed-local-1.4.rar as the archive, and library-ds.xml as the plan file. Then deploy the cmp-jpa-ejb.jar, followed by cmp-ejb-web.war. Finally, access the URL http://localhost:8080/library/LibraryServlet?op=commit. We can now verify that two entries were added to the MEMBERS table and one entry has been added to the BOOKS table in LIBRARYDB.

Bean-managed persistence

The use of @PersistenceUnit annotation on the EntityManagerFactory field results in the container injecting an EntityManagerFactory. The EntityManager is created from the EntityManagerFactory. The EntityManager's persistent context does not propagate with any active transactions. Therefore, the references to EntityManager corresponding to the same persistence unit will have a different persistence context across different components, which means that the modifications done to entities through one entity manager reference are not visible through the other entity manager references. The default persistence scope of the application-managed entity manager is EXTENDED. The transaction-type can be one of the JTA, in which case the EntityManager can join a transaction by calling the joinTransaction() method, or RESOURCE_LOCAL, in which case the EntityManager does not join the transaction. The lifecycle of the entity manager is not managed by the container, and it is the responsibility of the application to destroy the entity manager objects.

BMP sample application

The sample library application demonstrating Bean-Managed Persistence contains two entity classes, namely, Member and Book, and a stateless session bean named Library2Bean. The session bean implementation class is shown below:

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class Library2Bean implements Library { @PersistenceUnit(unitName="LibraryUnit") private EntityManagerFactory emf;
private EntityManager em;
@PostConstruct
public void init(){
em = emf.createEntityManager();
}
@PreDestroy
JPA applicationsBMP, sample applicationpublic void destroy(){
em.close();
}
public void addBook(String name, String author) {
em.joinTransaction();
Book book = new Book();
book.setBookId((int)System.nanoTime());
book.setName(name);
book.setAuthor(author);
em.persist(book);
}
...
}

Notice that the EntityManagerFactory will be injected by the container into the session bean field emf. The session bean creates the EntityManager instance in the init() method and closes the EntityManager in the destroy() method. Also, notice that the business methods invoke joinTransaction() to join the transaction. The persistence.xml file for this application is as given below:

<?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="LibraryUnit" transaction-type="JTA">
<description>BMP w JPA</description>
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl </provider>
<jta-data-source>LibraryDS</jta-data-source>
<class>sample.jpa.Member</class>
<class>sample.jpa.Book</class>
</persistence-unit>
</persistence>

Notice the two entity classes Member and Book that are associated with the persistence unit LibraryUnit.

The deployment plan openejb-jar.xml for this application is given below:

<?xml version="1.0" encoding="UTF-8"?>
<openejb-jar xmlns="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.2">
<sys:environment>
<sys:moduleId>
<sys:groupId>packt.samples</sys:groupId>
<sys:artifactId>bmp-jpa-ejb</sys:artifactId>
<sys:version>2.0</sys:version>
<sys:type>jar</sys:type>
</sys:moduleId>
<dependencies>
<dependency>
<groupId>console.dbpool</groupId>
<artifactId>LibraryDS</artifactId>
<type>rar</type>
</dependency>
</dependencies>
</sys:environment>
<enterprise-beans/>
</openejb-jar>

This application also uses the same LibraryDS database pool as the CMP sample application. Therefore, we do not need to create a new database and database pool. To run the application, first deploy bmp-jpa-ejb.jar and then deploy bmp-ejb-web.war. Access the URL http://localhost:8080/library2/LibraryServlet? op=commit. We can now verify that two entries were added to the MEMBERSBMP table and one entry was added to the BOOKSBMP table in LIBRARYDB.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset