Browse DevX
Sign up for e-mail newsletters from DevX


Banish Your Resistance to Persistence with the EJB 3.0 Persistence API : Page 3

With the 3.0 version of EJB, Java's guardians have endeavored to make persistence a gentler beast that borrows the best from other ORM frameworks that have long curried favor with the community. Now, learn how to use the new spec, along with JBoss and Maven, to persist Java objects to a relational database.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

The Entity Manager API
The three key concepts behind persistence in EJB 3.0 are the persistence unit, persistence context, and the entity manager.

A persistence unit is a set of classes that are mapped to a single data store. These classes are typically packaged into a single persistence archive (PAR), which associates these classes and their mapping metadata with a named entity manager. Persistence archives will be discussed in more depth later in this article.

The EJB 3.0 specification defines a persistence context as "a set of entity instances in which—for any persistent entity identity—there is a unique entity instance." In most cases this means that a persistence context is the set of entities associated with a particular transaction.

The entity manager is the primary interface for your programs to interact with the underlying persistence engine. An entity manager is associated with a particular persistence context and provides methods to create, update, and delete entities (among other functions).

You typically obtain an entity manager either through dependency injection or by looking up the entity manager through JNDI. In order for the container to inject an entity manager into your class you must declare a field of type EntityManager and annotate it with the @PersistenceContext annotation. This annotation specifies which persistent unit to retrieve an entity manager for and matches the unit name specified in the persistence archive. This is the simplest approach for obtaining an entity manager and is illustrated below in the OrderProcessor message-driven bean begun in the first article.

public class OrderProcessor implements MessageListener { @PersistenceContext(unitName = "musicStoreDB") protected EntityManager em; ... }

Once you have obtained an entity manager reference you can use the entity manager interface to store and retrieve persistent entities. For example, to store a MusicOrder you can invoke the persist() method on the entity manager. Below you'll find the OrderProcessor, which has been enhanced to receive an order via JMS and save it to the database:

public class OrderProcessor implements MessageListener { @PersistenceContext(unitName = "musicStoreDB") protected EntityManager em; public void onMessage(Message message) { ObjectMessage objectMessage = (ObjectMessage) message; try { MusicOrder order = (MusicOrder) objectMessage.getObject(); em.persist(order); } catch (JMSException e) { e.printStackTrace(); } } }

In addition to using the EnityManager class to persist entities, you can also use it to find particular entities by their identifying primary key. The MusicStoreDAO contains several examples of this:

public class MusicStoreDAO implements IMusicStoreDAO { @PersistenceContext(unitName = "musicStoreDB") protected EntityManager em; ... public Artist findArtistById(int id) { return em.find(Artist.class, id); } public Genre findGenreById(int id) { return em.find(Genre.class, id); } public Product findProductById(int id) { return em.find(Product.class, id); } ... }

The EntityManager retrieves a unique entity from persistent storage via a class and a primary key object. The actual definition of the find method of the EntityManager is shown below:

/** * Find by primary key. * @param entityClass * @param primaryKey * @return the found entity instance or null * if the entity does not exist * @throws IllegalArgumentException if the first argument does * not denote an entity type or the second * argument is not a valid type for that * entity’s primary key */ public <T> T find(Class<T> entityClass, Object primaryKey);

There are a couple of points to take note of here. First, this method uses generics to match the return type of the method to the entityClass parameter. This avoids having to make the self-obvious cast from Object to the type of object you are retrieving. Also notice that although the second parameter expects an object I am passing a primitive integer instead. The Java 5 JRE is autoboxing the primitive into an Integer object before passing it on to the EntityManager.

In addition to allowing you to retrieve individual objects via the find method, the EntityManager also features a query language that you can use to perform more complex queries against your persisted entities. This query language is named EJB QL and more information on this can be found in the EJB 3.0 specification. An example of this from the music store application, and also from the MusicStoreDAO, is shown below:

public class MusicStoreDAO implements IMusicStoreDAO { @PersistenceContext(unitName = "musicStoreDB") protected EntityManager em; ... @SuppressWarnings("unchecked") public List<Genre> listGenres() { return (List<Genre>) em.createQuery("SELECT g FROM Genre g").getResultList(); } ... }

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date