ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

What's New in EJB 2.1?

by Emmanuel Proulx

Who said the JPC is slow?

Only a few J2EE application servers are following the EJB 2.0 specification, and already the EJB 2.1 draft specification is out. For you busy folks who want to know about what the future has in store for EJBs but don't have the time to read a 636-page document, here is a quick overview. Fair warning: the specification is a draft, so many parts are incomplete or will change.

Quick List of New Features

  • Message-driven beans (MDBs): can now accept messages from sources other than JMS.
  • EJB query language (EJB-QL): many new functions are added to this language: ORDER BY, AVG, MIN, MAX, SUM, COUNT, and MOD.
  • Support for Web services: stateless session beans can be invoked over SOAP/HTTP. Also, an EJB can easily access a Web service using the new service reference.
  • EJB timer service: a new event-based mechanism for invoking EJBs at specific times.
  • Many small changes: support for the latest versions of Java specifications, XML schema, and message destinations.

Message-driven Bean Enhancements

When the EJB 2.0 specification appeared, it introduced the idea of calling an EJB asynchronously, but you had to do it with JMS. JMS is not the only way to invoke an object asynchronously, however; other APIs exist, such as JAXM. How is this done with EJB 2.1?

Related Reading

Enterprise JavaBeans
By Richard Monson-Haefel

There are two things that differ. First, as you may know, in order to write an MDB class, it must implement some interfaces. These are javax.ejb.MessageDrivenBean and javax.jms.MessageListener. The latter is the interface that enables the EJB container to subscribe the bean to the JMS server. To make your EJB listen to another type of messaging server, the MDB must implement another interface. For example, in order to listen to JAXM messages, the MDB must implement javax.xml.messaging.OneWayListener or javax.xml.messaging.ReqRespListener.

As for the second difference, obviously, the configuration side of a JMS-MDB will differ from a non-JMS one. The EJB container must know which destination or endpoint to which it must connect. The configuration of the MDB is done with a new <messaging-type> tag, and by specifying "configuration properties" with the tag <activation-config-propertyType>. This contains arbitrary name/value pairs that are specific to the messaging service being used. It is more versatile than being forced to use JMS-specific tags, like <message-selector>.

The way non-JMS servers will plug into the EJB container is more or less overlooked in the current draft version of the specification. There is a mention of using the J2EE-CA, but no details are provided. This will probably be left to the EJB container to implement, just like persistence services.

EJB-QL Enhancements

When EJB-QL came out as a standard way to write queries, it was criticized for being a reinvention of the wheel. Don't we have already some querying languages, like SQL and XQuery? Plus, EJB-QL lacks several features that made it less than useful, in some cases. EJB 2.1 is trying to remedy these problems by extending the language to make it more SQL-like. Here are a few clauses and functions that are now added to this language.


Ordering is something that's usually more optimized when it's done by the database than when it's done on the client side. This new clause simply works by specifying which fields to sort on, and if data needs to be sorted in ascending or descending order. For example:

SELECT OBJECT(c) FROM ConsultantBean AS c ORDER BY c.city,c.startingDate DESC

returns all consultants sorted by city, starting with the most senior.


This numeric function returns the rest of the division between an integer and another integer (modulo). For example:

SELECT OBJECT(p) FROM PageBean AS p WHERE MOD(p.number,2) = 1

returns all odd-numbered pages.


AVG is an aggregate function that can be used for ejbSelect methods in the SELECT clause. It returns the average value of a specified field. For example:

SELECT AVG(e.salary) FROM EmployeeBean AS e

gets the average salary for all employees.


This aggregate function can be used for ejbSelect methods in the SELECT clause. It returns the minimum value of a specified field. For example:

SELECT MIN(f.nextFlightDate) FROM FlightBean AS f WHERE f.departureAirport = ?1 AND f.arrivalAirport = ?2

gets the date when the next flight is scheduled between two cities.


This aggregate function can be used for ejbSelect methods in the SELECT clause. It returns the maximum value of a specified field. For example:

SELECT MAX(c.age) FROM ClientBean AS c

returns the age of the oldest client.


This aggregate function can be used for ejbSelect methods in the SELECT clause. It adds up all values for a field. For example:

SELECT SUM(q.sales) FROM QuarterBean AS q WHERE q.year = ?1

calculates the total of all sales for a certain year.


This aggregate function counts the number of elements. It can only be used in ejbSelect methods and in the SELECT clause. For example:

SELECT COUNT(s) FROM StoreBean AS s WHERE s.city = ?1

counts the number of stores in a certain city.

About Aggregate Functions

The aggregate functions (AVG, MIN, MAX, SUM, and COUNT) can be used with DISTINCT to eliminate duplicates before calculating.

Personally, I don't see why all of these aggregate functions cannot be used in the WHERE clause, as well. The specification says these can be used in the SELECT clause only. It could be useful to test each record against a condition that uses an aggregate function. For example, getting all employees whose salary is above average:

SELECT OBJECT(e) FROM EmployeeBean AS e WHERE e.salary > AVG(e.salary)

One can work around this with an ejbSelect method, or in other ways.

Pages: 1, 2

Next Pagearrow