JPA Architecture

Q: Why use Ebean over EJB3's JPA in the first place?

A: The JPA architecture will give Developers unwanted complications when running outside of a container.

EntityManager and Session Management

EntityManager in JPA acts as a Session object for a user. In this sense the EntityManager can not be shared by different users in the system. This matches with the Hibernate Session object and similarly with Toplink ClientSession object.

In using JPA you (the Developer) will have to decide how to manage the EntityManager. You will choose between creating a new EntityManager instance for each Transaction or keeping the EntityManager and reusing the same EntityManager instance over multiple requests (Extended Persistence Context).

EntityManager (and Hibernate Session) are user Session objects.

Strategy: New EntityManager instance per Transaction

If you create a new EntityManager for each Transaction you will forgo Optimistic Concurrency Checking for Entity Beans that do not have a version property. Refer to Section 3.4 of the EJB3 Specification or better review the Hibernate documentation which seems much clearer in its explanation of this point.

Downside: No Optimistic Concurrency Checking for Beans without a Version property

Strategy: Manage EntityManager - Extended Persistence Context

If you keep the EntityManager (Extended Persistence Context) then you will keep Optimistic Concurrency Checking but you have the burden of managing the EntityManger objects. The natural way to manage the EntityManager with a EJB3 container is to use a Stateful Session Bean. If you wish to use EJB3 without a container you need another mechanisim to manage the EntityManager between Transactions (during user think time).

That is, to run outside a container you will need to provide Session Management for EntityManager objects.

In keeping a EntityManager open for an extended period of time you may also encounter issues with it filling up with old data. You may have to periodically call EntityManager.clear().

Downside: How to manage EntityManager during "User Think time"?

The heart of the Issue - 'Old values' and Optimistic Concurrency Checking

At the heart of this issue is the desire to provide Optimistic Concurrency Checking for Entity Beans that do not have a version property (AKA Tables without a version column).

More specifically, to provide Optimisitic Concurrency Checking in this scenario you need the 'Old Values' of the bean to use in the WHERE clause (ALL Column concurrency checking).

For JPA these 'Old values' are kept by the EntityManager. Without the EntityManager you do not have the 'Old values' and so can not build/bind the WHERE clause.

'Old values' are kept by the EntityManager

Where does Ebean keep 'Old Values'?

With Ebean the 'Old values' are kept on the bean itself. More specifically method interception is used on the setter methods and when the bean is going to be changed for the first time, the bean copies itself keeping the original or 'Old Values'. In this way the bean has the 'Current/New values' aswell as the 'Original/Old values'.

Note that Entity Bean getter methods are intercepted to provide Lazy Loading (On Reference Objects) and so its not a big stretch to provide interception on the setter methods to support the creation of 'Old values'.

'Old values' are on the Entity beans themselves

What about other EntityManager tasks?

The EntityManager is involved in other tasks including 'Persistence Context', Cascading and Batching of Merge/Save/Delete as well as Lazy loading. These functions can all be supported without EntityManager and how they are performed is documented here [Lazy Loading] [Persistence Context] [Cascading Save/Delete]

It is worth noting that without an EntityManager the concept of Detached and Attached beans disappears.

NEXT: JPA API issues

Introduction User Guide (pdf) Install/Configure Public JavaDoc Whitepapers
General Database Specific Byte Code Deployment Annotations Features
Top Bugs Top Enhancements