Chapter 1. Architecture

1.1. Definitions

EJB3 is part of the Java EE 5.0 platform. Persistence in EJB3 is available in EJB3 containers, as well as for standalone J2SE applications that execute outside of a particular container. The following programming interfaces and artifacts are available in both environments.

EntityManagerFactory

An entity manager factory provides entity manager instances, all instances are configured to connect to the same database, to use the same default settings as defined by the particular implementation, etc. You can prepare several entity manager factories to access several data stores. This interface is similar to the SessionFactory in native Hibernate.

EntityManager

The EntityManager API is used to access a database in a particular unit of work. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities. This interface is similar to the Session in Hibernate.

Persistence context

A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle is managed by a particular entity manager. The scope of this context can either be the transaction, or an extended unit of work.

Persistence unit

The set of entity types that can be managed by a given entity manager is defined by a persistence unit. A persistence unit defines the set of all classes that are related or grouped by the application, and which must be collocated in their mapping to a single data store.

Container-managed entity manager

An Entity Manager whose lifecycle is managed by the container

Application-managed entity manager

An Entity Manager whose lifecycle is managed by the application.

JTA entity manager

Entity manager involved in a JTA transaction

Resource-local entity manager

Entity manager using a resource transaction (not a JTA transaction).

1.2. EJB container environment

1.2.1. Container-managed entity manager

The most common and widely used entity manager in a Java EE environment is the container-managed entity manager. In this mode, the container is responsible for the opening and closing of the entity manager (this is transparent to the application). It is also responsible for transaction boundaries. A container-managed entity manager is obtained in an application through dependency injection or through JNDI lookup, A container-managed entity manger requires the use of a JTA transaction.

1.2.2. Application-managed entity manager

An application-managed entity manager allows you to control the entity manager in application code. This entity manager is retrieved through the EntityManagerFactory API. An application managed entity manager can be either involved in the current JTA transaction (a JTA entity manager), or the transaction may be controlled through the EntityTransaction API (a resource-local entity manager). The resource-local entity manager transaction maps to a direct resource transaction (i. e. in Hibernate's case a JDBC transaction). The entity manager type (JTA or resource-local) is defined at configuration time, when setting up the entity manager factory.

1.2.3. Persistence context scope

An entity manager is the API to interact with the persistence context. Two common strategies can be used: binding the persistence context to the transaction boundaries, or keeping the persistence context available across several transactions.

The most common case is to bind the persistence context scope to the current transaction scope. This is only doable when JTA transactions are used: the persistence context is associated with the JTA transaction life cycle. When a entity manager is invoked, the persistence context is also opened, if there is no persistence context associated with the current JTA transaction. Otherwise, the associated persistence context is used. The persistence context ends when the JTA transaction completes. This means that during the JTA transaction, an application will be able to work on managed entities of the same persistence context. In other words, you don't have to pass the entity manager's persistence context across your EJB method calls, but simply use dependency injection or lookup whenever you need an entity manager.

You can also use an extended persistence context. This can be combined with stateful session beans, if you use a container-managed entity manager: the persistence context is created when an entity manager is retrieved from dependency injection or JNDI lookup , and is kept until the container closes it after the completion of the Remove stateful session bean method. This is a perfect mechanism for implementing a "long" unit of work pattern. For example, if you have to deal with multiple user interaction cycles as a single unit of work (e.g. a wizard dialog that has to be fully completed), you usually model this as a unit of work from the point of view of the application user, and implement it using an extended persistence context. Please refer to the Hibernate reference manual or the book Hibernate In Action for more information about this pattern. JBoss Seam is a framework tht link together JSF and EJB3 around the notion of conversation and unit of work. For an application-managed entity manager the persistence context is created when the entity manager is created and kept until the entity manager is closed. In an extended persistence context, all modification operations (persist, merge, remove) executed outside a transaction are queued until the persistence context is attached to a transaction. The transaction typically occurs at the user process end, allowing the whole process to be commited or rollbacked. For application-managed entity manager only support the exctended persistence context.

A resource-local entity manager or an entity manager created with EntityManagerFactory.createEntityManager() (application-managed) has a one-to-one relationship with a persistence context. In other situations persistence context propagation occurs.

1.2.4. Persistence context propagation

Persistence context propagation occurs for container-managed entity managers.

In a transaction-scoped container managed entity manager (common case in a Java EE environment), the JTA transaction propagation is the same as the persistence context resource propagation. In other words, container-managed transaction-scoped entity managers retrieved within a given JTA transaction all share the same persistence context. In Hibernate terms, this means all managers share the same session.

Important: persistence context are never shared between different JTA transactions or between entity manager that do not came from the same entity manager factory. There are some noteworthy exceptions for context propagation when using extended persistence contexts:

  • If a stateless session bean, message-driven bean, or stateful session bean with a transaction-scoped persistence context calls a stateful session bean with an extended persistence context in the same JTA transaction, an IllegalStateException is thrown.

  • If a stateful session bean with an extended persistence context calls as stateless session bean or a stateful session bean with a transaction-scoped persistence context in the same JTA transaction, the persistence context is propagated.

  • If a stateful session bean with an extended persistence context calls a stateless or stateful session bean in a different JTA transaction context, the persistence context is not propagated.

  • If a stateful session bean with an extended persistence context instantiates another stateful session bean with an extended persistence context, the extended persistence context is inherited by the second stateful session bean. If the second stateful session bean is called with a different transaction context than the first, an IllegalStateException is thrown.

  • If a stateful session bean with an extended persistence context calls a stateful session bean with a different extended persistence context in the same transaction, an IllegalStateException is thrown.

1.3. Java SE environments

In a Java SE environment only extented context application-managed entity managers are available. You can retrieve an entity manger using the EntityManagerFactory API. Only resource-local entity managers are available. In other words, JTA transactions and persistence context propagation are not supported in Java SE (you will have to propagate the persistence context yourself, e.g. using the thread local session pattern popular in the Hibernate community).

Extended context means that a persistence context is created when the entity manager is retrieved (using EntityManagerFactory.createEntityManager(...) ) and closed when the entity manager is closed. Many resource-local transaction share the same persistence context, in this case.