Hibernate is arguably one of the finest persistence engines ever written for the Java language. I remember fondly the first time I started working with Hibernate and gleefully transitioning the project we were working on over to it. At the time, we had an in-house persistence engine that was a huge drain on resources and never truly worked properly. Hibernate solved our persistence problems in a flash. It truly was a godsend. Fast forward to the present. EJB 3.0 is on the horizon, and soon we will be planning our transitions from current EJB 2.x servers. Taking a look at the persistence changes in EJB 3.0, one has to wonder—is this just a cut and paste from Hibernate? Did Sun really just steal the design from Hibernate? The answer is a little more complex.
One of the mandates for EJB 3.0 was to make it more useful and easier to develop against. Linda DeMichiel of Sun Micosystems realized that to accomplish this goal, EJB 3.0 had to be based on the existing libraries that developers are using today; otherwise, it would cause a difficult transition and probably be ignored. So members from Oracle, JBoss, Apache, BEA, Novell, Google, and other field experts were invited to participate in the specification. The goal of this group was to produce a specification that would make EJBs easier to develop and to create a persistence standard that developers could transition over to easily.
As this team began developing the EJB 3.0 specification, certain features were realized to be functionally the same across all of the major vendors and libraries (these features are discussed in the following sections).
The EntityManager is responsible for handling a transaction. In JDO it is called the PersistenceManager, and Hibernate calls it a Session. In the GlassFish project, EntityManager is described as follows:
An EntityManager instance is associated with a 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 are managed. This interface defines the methods that are used to interact with the persistence context. The EntityManager API is used to create and remove persistent entity instances, to find entities by their primary key, and to query over entities.
The set of entities that can be managed by a given EntityManager instance 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 co-located in their mapping to a single database.
A named query is a query that is predefined and then assigned to a name so that it can be accessed by that name at a later date. In database lingo, named queries would be called stored procedures. When combined with native queries (listed below), database queries just got a lot less painful.
Instead of using the Entity Query Language which can be quite limiting, native queries would allow the full power of the SQL language to be used directly from the EJBs. It should now be possible to call count(), max(), and others on the database without having to jump through a lot of hoops.
Callback listeners are event listeners or in database terms, triggers. They enable the ability to call a piece of code when an event occurs.
The ability to leave the scope of an EntityManager and return to be persisted is something that was completely missing prior to EJB 3.0. Previously, the values from an object had to be copied into a POJO (Plain Old Java Object) and then copied back to accomplish this.
Prior to EJB 3.0, I would use value-objects and copy the values from the EJB into a POJO and then use that object in the front-end. If a value were changed in the POJO, it would have to be pushed back to the EJB and then the values copied back over. This mess is now gone. An object can even leave the JVM completely and return at a later date and be reattached. The efficiency of this change cannot be overstated.
O/R Mapping Types
Being able to map fields in an EJB directly to the columns in a database was something that was abstracted away prior to EJB 3.0. This abstraction did not work well, and a lot of third-party tools put it back. One of my favorite features from xDoclet was the ability to define what SQL type each persistent field was in my EJB. With EJB 3.0 and Annotations, a third-party tool is no longer necessary.