The two most significant changes in the proposed EJB 3.0 specification are the use of the program annotation facility introduced in Java 5 and the new O/R mapping model based on Hibernate.
Hibernate is a popular, open source O/R mapping framework for Java environments, meant to shield developers from most common data-persistence-related programming tasks. It also has a specific Hibernate Query Language (HQL), imprints of which can be seen in the new EJB QL. Hibernate offers facilities for data retrieval and update, connection pooling, transaction management, declarative entity relationship management, and declarative and programmatic queries.
Bird’s eye view
The changes in the proposed EJB 3.0 specification can be divided into two categories:
• An annotation-based EJB programming model, in addition to the EJB 2.1 model of defining an application’s behaviour through deployment descriptors and several interfaces.
• The new persistence model for entity beans. EJB QL has also changed significantly.
There are also several side effects to these proposals, like a new client-programming model, use of business interfaces, and an entity bean life cycle. Please note that the EJB 2.1 programming model (with deployment descriptors and home/remote interfaces) is still valid. The new simplified model does not entirely replace the EJB 2.1 model.
One of the expert group’s important goals is to reduce the number of artifacts a bean provider must provide, and the group has done a pretty neat job in reaching that goal. In the EJB 3.0 world, all kinds of enterprise beans are just plain old Java objects (POJO) with appropriate annotations. Annotations can be used to define the bean’s business interface, O/R mapping information, resource references, and just about anything else that was defined through deployment descriptors or interfaces in EJB 2.1. Deployment descriptors are no longer required; the home interface is gone, and you don’t necessarily have to implement a business interface (the container can generate it for you).
For example, you declare a stateless session bean by using the @Stateless annotation on the Java class. For stateful beans, the @Remove annotation is marked on a particular method to indicate that the bean instance should be removed after a call to the marked method completes.
To reduce the amount of information you must specify for a component, the expert group has adopted a configuration-by-exception approach, meaning you provide intuitive defaults for all annotations so that most of the common information can be inferred.
The new persistence model
The new entity beans are also just POJOs with a few annotations and are not persistent entities by birth. An entity instance becomes persistent once it is associated with an EntityManager and becomes part of a persistence context. A persistence context is loosely synonymous with a transaction context; in strict words, it implicitly coexists with a transaction’s scope.
The entity relationships are also defined through annotations. In addition, O/R mapping is also done through annotations, and support for several database-specific operations is provided. With EJB 2.1, developers used their own design patterns or employed nonportable techniques (for example, auto key generation strategies).
It’s now time to get into the specifics of proposals made in the EJB 3.0 early draft. Let’s start with all four types of enterprise beans and then move on to the proposals generic to the whole of the EJB programming model.
Stateless session beans:
A stateless session bean (SLSB), written the EJB 3.0 way, is just a plain Java file with a class-level annotation of @Stateless. The bean class can implement the javax.ejb.SessionBean interface, but is not required to (and typically will not).
An SLSB doesn’t have a home interface anymore—in fact, no EJB type requires it. The bean class may or may not implement a business interface. If it does not implement any business interfaces, a business interface will be generated using all the public methods. If only certain methods should be exposed in the business interface, all of those methods can be marked with the @BusinessMethod annotation. By default, all generated interfaces are local, but the @Remote annotation can be used to indicate that a remote interface should be generated.
Stateful session beans
The story with stateful session beans (SFSB) is pretty much the same for SLSB, except for a couple of SFSB-specific points:
• An SFSB should have a way of initializing itself (provided through the ejbCreate() method in EJB 2.1 and earlier). The EJB 3.0 specification suggests that such initialization methods be provided as custom methods and exposed through the bean’s business interface. The onus now lies with the client to call appropriate initialization methods before using the bean. The expert group is still debating the need for providing an annotation that marks a particular method for initialization.
• The bean provider may mark any SFSB method with the @Remove annotation to indicate that the bean instance must be removed after the annotated method is called. Again, the expert group is still discussing whether a facility is necessary for indicating that the bean must not be removed if the method doesn’t complete normally.
Entity beans are marked with the @Entity annotation, and all properties/fields in the entity bean class not marked with the @Transient annotation are considered persistent. Entity bean persistent fields are exposed through JavaBean-style properties or just as public/protected Java class fields.
Entity beans can use helper classes for representing entity bean state, but instances of these classes don’t have a persistent identity. Instead, their existence is tied strongly to the owning entity bean instance; also these objects are not shareable across entities.
EJB 3.0 supports both unidirectional and bidirectional relationships between entity beans, which can be one-to-one, one-to-many, many-to-one, or many-to-many relationships. However, the two sides of a bidirectional relationship are distinguished as the owning side and the inverse side. The owning side is responsible for propagating relationship changes to the database. For many-to-many associations, the owning side must be explicitly specified. Actually it’s the reverse side that is specified by the isInverse=true annotation member on the reverse side’s ManyToMany annotation; from that, the owning side is deduced. Now, didn’t the expert group say it was making EJB easier?
The O/R mapping model has also significantly changed from the abstract-persistence-schema-based approach to a Hibernate-inspired one. Though the expert group is still discussing the model, and a clear picture will emerge only with the next draft, this draft features clear indications of the overall approach.
For one, the O/R mapping will be specified in the entity bean class itself by annotations. Also, the approach is to refer to concrete tables and columns instead of the abstract persistence schema. The O/R mapping model has intrinsic support for native SQL; that is, support at a deeper level, not just the ability to run native SQL queries. For example, the column definitions annotation (@Column) has a member columnDefinition that can be something like columnDefinition=”BLOB NOT NULL”.
Client programming model
An EJB client can acquire a reference to the bean’s business interface using the injection mechanism (@Inject annotation). Using the newly introduced @javax.ejb.EJBContext.lookup() method is another approach. But the specification is not clear as to how a standalone Java client acquires reference to a bean instance since the standalone Java clients run in a J2EE client container and lack access to the @javax.ejb.EJBContext object. There is yet another mechanism—a newly introduced universal context object: @javax.ejb.Context(). But, again, the spec does not say how this object can be used in a client container.
Happy EJB 🙂