In December 1999, Sun Microsystems released the final specification of Enterprise JavaBeans 1.1. Enterprise JavaBeans 1.1 is, in many ways, a point release with corrections and clarifications over EJB 1.0 that allows vendors and bean developers to create more portable beans. This appendix summarizes the most important and visible modifications to the specification made in EJB 1.1.
The biggest changes between EJB 1.0 and EJB 1.1 include mandating entity bean support, the adoption of XML deployment descriptors, the creation of a default JNDI context, and changes to security.
EJB 1.1 mandates support for the [a-z]ntity bean type. In EJB 1.0, entity bean support is optional, which means vendors can support them in whole, in part, or not at all. Most EJB server vendors chose to support entity beans in some way; for these vendors, the transition to full support shouldn’t be difficult. For most EJB developers, the required support for entity beans is welcomed because it provides a more stable platform for portable beans.
The entity bean type itself has undergone some changes. The bean-managed transaction option has been removed from entity beans. This option is difficult to use because it requires explicit transactional control by the developer. Removing it from entity beans simplifies the EJB architecture. Stateful session beans, however, still retain the option of managing their own transactions.
Another welcome change is the expansion of valid return types from
the find methods for entity beans. In EJB 1.0, find methods can
return a single entity or a collection of entities. Find methods that
return a single entity return the entity’s remote interface
type; entities that return a collection use
java.util.Enumeration
. In EJB 1.1, a new return
type has been added, java.util.Collection
. This
addition provides both the vendors and developers with more
flexibility in how the find methods are implemented and used.
A seemingly minor change to the return value of
ejbCreate()
may turn out to be a headache when
upgrading systems from EJB 1.0 to the EJB 1.1 specification. Because
the ejbCreate()
method works differently in
bean-managed and container-managed beans, EJB 1.0 specified different
return values: bean-managed entities return the unique identity of
the bean, the primary key; container-managed entities return void.
The following code shows the different method signatures used for
container-managed and bean-managed ejbCreate()
methods in EJB 1.0:
// container-managed entity, EJB 1.0 public class AccountCMP implements javax.ejb.EntityBean { public int id; public double balance; publicvoid
ejbCreate(int myID) { id = myID; } // more bean code follows } // bean-managed entity, EJB 1.0 public class AccountBMP implements javax.ejb.EntityBean { public int id; public double balance; publicAccountPK
ejbCreate(int myID) { id = myID; // do a database insert using JDBC AccountPK pk = new AccountPK(myID); return pk; } // more bean code follows }
The EJB 1.1 specification changes this so that both bean-managed and
container-managed entities have to return the primary key type from
the ejbCreate()
methods. However,
container-managed beans are required to return
null
instead of a primary key object. This
seemingly bizarre change was made to accommodate EJB vendors who want
to support container-managed beans by extending them with generated
bean-managed classes. The generated subclasses override the
ejbCreate()
methods to manually insert a record
into the database. In EJB 1.0, the ejbCreate()
methods in bean-managed and container-managed entities have different
return values, so extending the class and overriding the
ejbCreate()
methods doesn’t work. By
specifying that the ejbCreate()
methods must
always return the primary key class, container-managed beans can be
extended to create bean-managed beans. Unfortunately, this change
breaks forward compatibility with EJB 1.0 container-managed beans,
forcing bean developers to make changes to their existing code if
they want to transition to the EJB 1.1 specification.
The EJB 1.1 specification also contains some other changes regarding
the primary key class. For bean-managed persistence, EJB 1.1 states
that the primary key class can be any valid Java RMI-IIOP
type—a clear indication that IIOP will be the standard
distributed object protocol for EJB in a future version of the
specification. In addition, the new specification requires the
primary key class to implement the Object.equals()
and Object.hashCode()
methods to ensure that these
methods evaluate properly when comparing keys and storing them in a
java.util.Hashtable
. The most significant change
regarding primary keys is the option to defer their definition until
deployment time. In other words, the primary key for an entity bean
doesn’t have to be defined by the developer, but can be left to
the deployer. This is a significant departure from the previous
specification, which required the bean developer to define the
primary keys. By deferring the definition until deployment,
persistence mapping becomes more flexible, allowing beans to become
more portable. Although this is a convenient option, it’s
likely that most bean developers will continue to specify the primary
class when they develop the bean.
Finally, a change in the EJB 1.1 specification allows entity bean
references to be container-managed fields. In container-managed
persistence, the container manages persistence automatically, so it
must be told at deployment time which fields are persistent and how
to map them to the database. In EJB 1.0, container-managed fields are
limited to primitives and java.io.Serializable
types. Limiting the container-managed fields to these simple types
makes it more difficult to maintain persistent relationships to other
entity beans; entity beans are always referenced using their
java.rmi.Remote
interface type, which is neither a
primitive nor Serializable
. EJB 1.1 specifies that
container-managed fields can include references to other entity
beans, which makes it much easier for the bean developer to model
associations and aggregations of beans. How the container persists
the relationships is not specified, but it’s likely that
options for converting the reference to a primary key will be
provided at deployment time.