Home > Guides > Programming > Java

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Enterprise Java Beans (EJB) 3.0

Last updated Dec 22, 2005.

EJB3

The Enterprise JavaBeans 3.0 specification is the biggest thing to hit Enterprise Java since its inception. While not yet in its final draft, EJB 3.0 is quite a ways along, and JBoss has an implementation. It is time to prepare for the revolution.

The public review draft was published in June 2005 and resoundingly approved in August 2005 by its executive committee. You can read it in JSR 220. The draft comes in the form of three documents:

  • EJB3 Core: describes the core contracts and requirements that EJB3 implementations must provide to be EJB3 compliant. It shows bean life cycles and the behaviors you can expect from your code.
  • EJB3 Persistence: provides a detailed description of EJB3 persistence, specifically the new mechanisms for developing entity beans and defining the relationships and queries between them.
  • EJB3 Simplified: provides an overview of the new simplified API for developing EJB3 components.

Overview

The EJB3 API has greatly simplified the development of Enterprise JavaBeans by removing deployment descriptors and many burdensome interfaces that quickly became points of update contentions. Furthermore, through the Java 5 concepts of dependency interjection, EJB and dependency lookups are a snap! If you have already used tools like Hibernate, then most of the new EJB API will look somewhat familiar. In any case, the new API is easy to use and significantly reduces redundancy.

The core strengths of the new EJB API come through Java 5 annotations. Annotations are basically "decorators" that you can add to your code, that do not directly affect the code's semantics, but rather affect the way that tools and libraries treat your code. It has always been problematic trying to maintain helper classes and deployment descriptors. For example, for each entity bean, you had to maintain a deployment descriptor listing its home, remote, and local interfaces as well as keep those interfaces in synch with your bean implementation class. Through annotations, however, you can denote a class as a an entity bean and denote bean fields as participating in a relationship; the EJB deployer can dynamically generate deployment descriptors, interfaces, and CMR-style relationships to manage your beans.

EJB3 beans are "Plain Old Java Objects", or POJOs, with annotations telling the EJB deployer how to treat them. For example, listing 1 shows a complete entity bean.

Listing 1. ForumBean.java

package com.javasrc.forums.entity;

import javax.persistence.*;
import java.io.Serializable;
import java.util.*;

@Entity
@Table(name = "forum" )
public class ForumBean implements java.io.Serializable
{
  private int id;
  private String name;
  private String description;
  private Collection<TopicBean> topics = new TreeSet();

  public ForumBean()
  {
  }

  public ForumBean( String name, String description )
  {
    this.name = name;
    this.description = description;
  }

  @Id(generate = GeneratorType.AUTO)
  public int getId()
  {
    return this.id;
  }

  public void setId( int id )
  {
    this.id = id;
  }

  public String getName()
  {
    return this.name;
  }

  public void setName( String name )
  {
    this.name = name;
  }

  public String getDescription()
  {
    return this.description;
  }
 
  public void setDescription( String description )
  {
    this.description = description;
  }

  @OneToMany(mappedBy = "forum")
  public Collection<TopicBean> getTopics()
  {
    return this.topics;
  }

  public void setTopics( Collection<TopicBean> topics )
  {
    this.topics = topics;
  }
}

The "@Entity" annotation denotes that the bean is an entity bean and the EJB deployer should treat it as such. Additionally, the "@Table" annotation tells the persistence engine to persist the the object to the "forum" table. The "@Id" annotion identifies the "id" attribute as the primary key and denotes that it is an auto-generated value. Finally, the "@OneToMany" annotation creates a one-to-many relationship between Forums and Topics; a forum can have many topics, but a topic may only belong to a single forum. The relationship is maintained through the topic's "forum" field.

We'll go through defining entity bean in brutal detail later in this series. The purpose of this example is not to teach you how to write entity beans, but rather to give you a feel for what annotations are what our new beans will look like.

Annotations

Technically, annotations are defined as special types of interfaces, denoted by the @interface keyword, that contain the types and identifiers for the series of optional and mandatory parameters contained by an annotation. The Java 5 documentation provides the following example:

/**
 * Describes the Request-For-Enhancement(RFE) that led
 * to the presence of the annotated API element.
 */
public @interface RequestForEnhancement {
  int  id();
  String synopsis();
  String engineer() default "[unassigned]"; 
  String date();  default "[unimplemented]"; 
}

Then this annotation can be called out by a method in one of your classes:

@RequestForEnhancement(
  id    = 2868724,
  synopsis = "Enable time-travel",
  engineer = "Mr. Peabody",
  date   = "4/1/3007"
)
public static void travelThroughTime(Date destination) { ... }

The Method class that we can obtain through the reflection and introspection APIs contains new methods to discover and interact with annotations: isAnnotationPresent(), getAnnotation(), getParameterAnnotations() and getDeclaredAnnotations(). These APIs provide access to java.lang.annotation.Annotation implementations through which you can gain access to annotation values.

The EJB deployer therefore uses this mechanism to dynamically identify bean types and generate the appropriate "glue" to hook beans in to the application infrastructure. Taking these annotations a step further, they can be used with the new dependency injection design pattern by the EJB deployer to dynamically inject references to other beans and resources. For example, there is a new @EJB annotation tag that can be added to a Stateless Session Bean to require the container (application server) to perform a JNDI lookup and inject a reference to another bean:

@Stateless
public class MyStatelessSessionBean implements MyStatelessSession
{
 ...
 @EJB Forum forum;

 @EJB
 public void setForum( ForumBean forum ) {
  this.forum = forum;
 }
 ...
}

Unfortunately, this only works from inside EJBs (you still have to perform the lookups in your web tier), but it greatly simplifies inter-bean lookups. This same mechanism can be used to inject resource dependencies such as database connections.

Project

Rather than walk through several trivial examples, I thought it would be a good exercise to develop a larger-scale project using the different EJB3 component technologies together. Therefore, I crafted the design for a message forum application. Figure 79 shows the object model for the project.

Figure 79

Figure 79. Forum Message Board Data Model

In this application, we have the notion of a forum that contains topics. Each topic may contain sub-topics. And each topic and sub-topic may contain messages. Messages are posted by users and each message may have zero or more replies. Furthermore, messages may be cross-posted to multiple topics. This yields the following entities:

  • Forum
  • Topic
  • Message
  • JSUser

And the following relationships:

  • Forum has a one-to-many relationship with Topic
  • Topic has a one-to-many relationship with itself (sub-topics)
  • Topic has a many-to-many relationship with Message
  • Message has a one-to-many relationship with itself (replies)
  • JSUser has a one-to-many relationship with Message

For our implementation, we will use JBoss with EJB3 support and MySQL. And we will use Ant to build our components.

Prerequisites

Before we start writing code, you need to obtain the correct versions of JBoss and MySQL and configure them to work together. JBoss version 4.0.3 SP1 ships with out-of-the-box support for EJB3 and can be downloaded here.

For this example, I assume that you have downloaded and installed version 4.0.3 SP1 (or later.)

You should be safe using any 5.x variation of MySQL. I downloaded and installed the latest version (as of this writing), which was 5.0.16, which you can download here. And you might want a GUI configuration application, so I recommend the MySQL Administrator, which can be downloaded here. And for creating schemas and tables, the MySQL Query Browser is very helpful.

After installing MySQL, the MySQL Administrator, and the MySQL Query Browser, start MySQL, launch the MySQL Query Browser and give your root password. In the schemata panel on the right, right-click and choose "Create New Schema", and give it the name "forum." This is shown in Figure 80.

Figure 80

Figure 80. MySQL Query Browser screenshot demonstrating how to add a new schema

Launch the MySQL Administrator and choose "User Administration." On the bottom of the right panel, choose "New User." Give the user the name "forum" and password "forum". Choose the "Schema Privileges" tab, select the "forum" schema, and assign all privileges to this user. This is shown in figure 81.

Figure 81

Figure 81. MySQL Administrator screenshot demonstrating how to add privileges to the forum user for the forum schema.

We'll construct the data model in the next section, but to configure MySQL to work with JBoss, you also need to download the MySQL Connector/J, for which the latest version is 3.1. This can be downloaded here.

Once you have downloaded and installed both JBoss and MySQL, the process to create a relationship between them is two-fold:

  1. Add the MySQL Connector/J to JBoss's classpath by copying it into the <jboss-home>/server/default/lib folder.
  2. Create a data source in JBoss's configuration.

The data source is created in JBoss by creating a new XML file and copying it to JBoss's server/default/deploy folder. This XML is shown in Listing 2.

Listing 2. forum-mysql-ds.xml

<?xml version="1.0" encoding="UTF-8"?>

<datasources>
  <local-tx-datasource>
    <!-- This connection pool will be bound into JNDI with the name
       "java:/MySQLDB" -->

    <jndi-name>ForumDS</jndi-name>
    <connection-url>jdbc:mysql://localhost:3306/forum</connection-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <user-name>forum</user-name>
    <password>forum</password>

    <min-pool-size>2</min-pool-size>

    <!-- Don’t set this any higher than max_connections on your
     MySQL server, usually this should be a 10 or a few 10’s
     of connections, not hundreds or thousands -->

    <max-pool-size>20</max-pool-size>

    <!-- Don’t allow connections to hang out idle too long,
     never longer than what wait_timeout is set to on the
     server...A few minutes is usually okay here,
     it depends on your application
     and how much spikey load it will see -->

    <idle-timeout-minutes>5</idle-timeout-minutes>

    <!-- If you’re using Connector/J 3.1.8 or newer, you can use
       our implementation of these to increase the robustness
       of the connection pool. -->

    <exception-sorter-class-name>com.mysql.jdbc.integration.jboss.ExtendedMysqlExceptionSorter</exception-sorter-class-name>
    <valid-connection-checker-class-name>com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker</valid-connection-checker-class-name>

  </local-tx-datasource>
</datasources>

This creates a new data source named "ForumDS" that accesses the MySQL instance running on the local machine named "forum":

jdbc:mysql://localhost:3306/forum

It logs on with username "forum" and password "forum".

If there are any variations to your configuration (such as you installed MySQL on a different machine or used a different username/password) then make changes as appropriate.

Start JBoss by executing the "run.bat" or "run.sh" file from its bin folder and watch the output. If successful, you should see a line that resembles the following:

10:10:03,550 INFO [ConnectionFactoryBindingService] Bound ConnectionManager ’jboss.jca:service=DataSourceBinding,name=ForumDS’ to JNDI name ’java:ForumDS’

If you are here, then you are ready to go!

Summary

EJB3 is a revolution in enterprise Java development. It provides all of the benefits of previous versions in terms of scalability and reliability, but it eliminates all the headaches of tedious and error-prone interfaces and deployment descriptors. I truly believe that EJB3 will bring more and better-quality enterprise applications to Java.

Join us as we build a complete EJB3-based application. Thus far we saw a high-level overview of EJB3 and the simplifications that Java 5 annotations have provided to the EJB3 API and setup a sample environment with JBoss and MySQL. We defined our forum application data model, built a set of Entity Beans, and used entity relationships to define relationships between them.

Next, we built a Stateless Session Bean that provided a programmatic front-end to interact and manage our Entity Beans. Finally we built a Servlet that exposes a simple URL-based interface to send commands to our Stateless Session Bean.

Next we will conclude the first iteration of our Forum application by building an Ant build script that builds and packages our application and complete all remaining deployment options.

We will continue the series by integrating a Struts-based fron-end to make everything "look good" and scale, so keep reading!

Online Resources

JBoss Download Page

MySQL 5.x Download Page

MySQL Connector/J Download Page

Official Documentation

JSR 220: Enterprise JavaBeans 3.0

Sun Documentation on Annotations

Discussions

Read and display the table in the document
Posted Nov 12, 2008 06:01 AM by StrongHead
1 Replies
Correction
Posted Nov 4, 2008 06:09 PM by youssef.mohammed
1 Replies
Instead of synchronising getInstance
Posted Nov 3, 2008 05:42 AM by grahamkelly
1 Replies

Make a New Comment

You must log in in order to post a comment.

Related Resources

Dustin SullivanIf You Are New to Java Programming...
By Dustin SullivanJune 2, 20092 Comments

We recently sat down with several top Java developers to talk about that state of the language as we approach this year's JavaOne.  As we were wrapping up, we threw one last question at them out of curiosity, and we thought you'd like to see what some of them said.

Steven HainesOracle Buys Sun of $7.4B
By Steven HainesApril 20, 2009 No Comments

In a stunning turn of events, Oracle steps in and buys Sun amist the breakdown of IBM's attempt to acquire Sun.

Steven HainesIBM in talks to buy Sun Microsystems for at least $6.5B
By Steven HainesMarch 18, 2009 No Comments

Reuters reported this morning that IBM is in talks to buy Sun Microsystems, which could "bolster their computer server products against rivals such as Hewlett-Packard Co."

See More Blogs

Informit Network