A .par
file is a jar file of the entity bean classes together with a simple configuration file META-INF/persistence.xml
. The persistence.xml
file defines the name of this persistence context. It tells the EJB 3.0 container which backend database (DataSource
) to use for this set of entity beans. The persistence.xml
file also contains implementation-specific configuration properties. For instance, JBoss EJB 3.0 is implemented on top of Hibernate 3.0. So you can pass any Hibernate configuration options in the persistence.xml
file. Here is an example persistence.xml
file with JBoss- and Hibernate-specific configuration properties on the SQL dialect and the second-level cache:
<entity-manager>
<name>cal</name>
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.cache.provider_class"
value="org.jboss.ejb3.entity.TreeCacheProviderHook"/>
<property name="hibernate.treecache.mbean.object_name"
value="jboss.cache:service=EJB3EntityTreeCache"/>
</properties>
</entity-manager>
The EntityManager
Once you have the entity beans deployed, you must access and manipulate them via the EJB 3.0 EntityManager
API. The EJB 3.0 container provides one EntityManager
object for each deployed persistence context (i.e., the .par
file). From an EJB 3.0 session bean POJO (see Part 1), you can inject the EntityManager
object via the @PersistenceContext
annotation and pass in the name of the context:
@Stateless
public class ManagerBean implements Manager {
@PersistenceContext (unitName="cal")
protected EntityManager em;
// Use "em"
// ... ...
}
Basic operations
To create a new data object and save it to the database, you can simply use the Java new
keyword to create the POJO and pass it to the EntityManager.persist()
method:
Person p = new Person ();
p.setName ("A new baby");
p.setDateOfBirth (new Date ());
em.persist (p);
To retrieve objects from the database, you can use the EJB 3.0 Query Language to search the database. The following example shows how to get all rows in the Person
database table to return as a collection of Person
Java objects:
// Get all persons
Collection <Person> persons = (Collection <Person>)
em.createQuery("from Person p").getResultList();
Managed POJOs
The objects saved and retrieved by the EntityManager
are managed in the persistence context. That means if the objects change later, the changes are automatically detected and persisted to the database. In the following example, we update a property of a managed POJO. The change is automatically detected by the EJB 3.0 container and sent to the database.
Person p = em.find(Person.class, personId);
p.setName ("Another Name");
// p is automatically updated to the database
// at the end of the current transaction.
// No additional API calls.
Since EJB 3.0 entity beans are just POJOs, they can be serialized and passed over the network. If an object is not created by the container (e.g., it is passed in from a network connection or is a return value from a remote procedure call), the persistence context does not manage it. You can merge a nonmanaged POJO into the persistence context by calling the EntityManager.merge()
method. Below is an example of merging a deserialized POJO into the current persistence context:
InputStream in;
// Initialize the input stream.
Person p = Util.deserialize (in);
// ... ...
em.merge (p);
// p is a managed object now. Any change to p
// is automatically detected and persisted.
p.setName ("Another Name");
Database synchronization
When the EntityManager
object is used in a session bean, it is tied with the server's transaction context. The EntityManager
commits and synchronizes its contents to the database when the server's transaction commits. In a session bean, the server transaction commits at the end of the call stack by default. Of course, you can also specify the detailed transactional properties of each business method via annotations. The example below shows how to declare a new transaction for a session bean method:
@TransactionAttribute(TransactionAttributeType.REQUIRESNEW)
public void update () {
// Update Person objects in this method
// and all updates are committed and flushed
// to the database at the end of this method.
}
Flushing database operations in a batch |
---|
To only flush changes to the database when a transaction commits, the container can group database operations in a batch and reduce the expensive database roundtrips. |
If you need to flush the updates to the database before the transaction commits, you can call the EntityManager.flush()
method explicitly. Or you may tag a method with the @FlushMode(FlushModeType.NEVER)
annotation, and the transaction manager will not flush the updates to the database at the end of this method (i.e., the end of the transaction). In this case, you can manually flush all database updates to achieve the most control.
In conclusion
EJB 3.0 provides a simple and effective framework for mapping Java POJOs to relational tables in SQL databases. It uses sensible default mapping strategies based on the structure and naming of the Java class. Yet you can also override any defaults and handle complex object relationships using a simple set of annotations.
The EJB 3.0 EntityManager
provides simple APIs to persist, find, and search objects from the database. Each EntityManager
object is associated with a set of mapped POJOs and has its own database settings. It is also automatically tied to the application server's transaction manager.
Learn more about this topic
- Part 1 of this series introduces the EJB 3.0 session bean and other POJO-based service objects"Simplify Enterprise Java Development with EJB 3.0, Part 1Use annotations to develop POJO services," Michael Yuan (JavaWorld, August 2005)
http://www.javaworld.com/javaworld/jw-08-2005/jw-0815-ejb3.html - Please refer to the JBoss EJB 3.0 TrailBlazer application for more entity beans and EntityManager examples. You can play with it online or download it from
http://www.jboss.com/docs/trailblazer - A list of learning trails most relevant to the contents covered in this article:
- Object-relational mapping basics in EJB 3.0
http://trailblazer.demo.jboss.com/EJB3Trail/persistence/orm/index.html - Package entity bean POJOs and define the persistence context
http://trailblazer.demo.jboss.com/EJB3Trail/persistence/config/index.html - How to use the EntityManager
http://trailblazer.demo.jboss.com/EJB3Trail/persistence/entitymanager/index.html
- Object-relational mapping basics in EJB 3.0
- Transaction and EntityManager
http://trailblazer.demo.jboss.com/EJB3Trail/services/transaction/index.html - Database update and synchronization
http://trailblazer.demo.jboss.com/EJB3Trail/persistence/updateentity/index.html
- The examples run in JBoss Application Server 4.0.3. Please check out the download and installation instructions here
http://trailblazer.demo.jboss.com/EJB3Trail/background/install/index.html - Michael Yuan's earlier JavaWorld article "On the Road to Simplicity" (February 2005) discusses the advantages of the POJO programming model over the old EJB 2.1
http://www.javaworld.com/javaworld/jw-02-2005/jw-0221-jboss4.html - "EJB 3.0 in a Nutshell" by Anil Sharma (JavaWorld, August 2004) is an analysis of EJB 3.0 based on an early version of the specification. It provides insights for the rationales behind the specification
http://www.javaworld.com/javaworld/jw-08-2004/jw-0809-ejb.html - Michael Yuan also writes about wireless development. Check out his past articles in JavaWorld's Wireless Java column
http://www.javaworld.com/columns/jw-wireless-index.shtml - For more articles on EJB, browse the Enterprise JavaBeans (EJB) section of JavaWorld's Topical Index
http://www.javaworld.com/channel_content/jw-ejbs-index.shtml? - For more articles on Java Enterprise Edition, browse the Java 2 Platform, Enterprise Edition (J2EE) section of JavaWorld's Topical Index
http://www.javaworld.com/channel_content/jw-j2ee-index.shtml?
This story, "Simplify enterprise Java development with EJB 3.0, Part 2" was originally published by JavaWorld.