Session Beans

Session beans are used to hold business logic and make it available in a distributed way. In fact, a session bean doesn’t do any processing on its own. Its method must be triggered by external programs or other beans. You can think of session beans as RPC services. Invoking a method on a bean starts some kind of processing and returns results. Session beans are short-lived; they are created by a client application or client bean for the duration of an application session. As soon as the application terminates, its session beans are no longer necessary.

As many applications involve accessing data, session beans may have to connect to a database and perform queries and updates and return results to the caller. In general, entity beans are used for all database access because that’s what they are made for. However, when only a few tables are accessed or whenever using entity beans doesn’t prove useful, session beans may access a database in much the same way as a standalone Java program does. The EJB framework doesn’t provide an API or technique to map session beans to database tables because that isn’t what they were created for: They don’t represent data from a database.

Stateless session beans

Session beans can be either stateless or stateful. Stateless beans don’t contain member attributes (class variables), only methods. A stateless bean doesn’t maintain data (that is, state) outside of method invocations. Session beans are stateless services where methods can be triggered from the outside world. Their methods perform processing of data (which can be mapped to a database if needed) and then return results to the caller when the method reaches its end.

An example of a stateless session bean that necessitates database access is a phonebook service. Such an object provides directory-based functions such as looking up phone numbers. It isn’t necessary to hold any kind of state outside the boundaries of the bean’s service methods. Consider a simple PhoneBook session bean that contains a single method called lookup(String namePattern) and returns an array of name-phone number pairs. Listing 10-1 illustrates the bean implementation for this example. Querying the database table containing all phone numbers is done at the time lookup is called, and for the simplicity of this example, no caching of results is performed.

Listing 10-1: A Stateless Session Bean

start example
// a stateless session bean import java.sql.*; import java.util.Hashtable; import javax.ejb.CreateException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; import javax.ejb.EJBException; import javax.naming.InitialContext; import javax.naming.NamingException; public class PhoneBookBean implements SessionBean {   public void ejbActivate() {   }   public void ejbRemove() {   }   public void ejbPassivate() {   }   public void ejbCreate () throws CreateException {   }   public Hashtable lookup(String namePattern) {     String query = "SELECT name, firstname, phone FROM phonebook" +         "ORDER BY name, firstname WHERE name LIKE ‘" + namePattern + "‘";     Hashtable results = new Hashtable();     try {       Connection conn = getConnection();       Statement stmt = conn.createStatement();       ResultSet rs = stmt.executeQuery(query);       while (rs.next()) {         results.put(rs.getString("name") + ", " + rs.getString("firstname"),           rs.getString("phone"));       }       stmt.close();       conn.close();     } catch (SQLException e) {       throw new EJBException(e);     }     return results;   }   private Connection getConnection() throws SQLException   {     InitialContext initCtx = null;     try {       initCtx = new InitialContext();       DataSource ds = (javax.sql.DataSource)         initCtx.lookup("java:comp/env/jdbc/databasePool");       return ds.getConnection();     } catch(NamingException ne) {       throw new EJBException(ne);     } finally {       try {         if(initCtx != null) initCtx.close();       } catch(NamingException ne) {         throw new EJBException(ne);       }     }   } }
end example

Listing 10-2 provides a simple client application that accesses the PhoneBook bean. Notice that there are no JDBC method calls made in the client: Accessing the database is the entire responsibility of the bean. After looking up a reference of a factory for the bean (PhoneBookHome), this client asks for the creation of the bean in the application server (home.create()) and then invokes its lookup method, passing a search string as a parameter. The intention is to retrieve all matching names, first names, and phone numbers for the provided name pattern and print them on the console. Next, the bean is destructed by calling the remove() method. Note that ejbCreate(), ejbRemove(), ejbActivate(), and ejbPassivate() of the bean itself are never called from within the client. They are reserved for use from the container.

Note 

It is beyond the scope of this book to explain the life cycle of beans and how a client can interfere in this cycle. If you want to obtain more information, please refer to the J2EE Reference Implementation documentation, available at http://java.sun.com/j2ee.

Listing 10-2: A Stateless Session Bean Client

start example
// a stateless session bean client import java.util.*; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; public class Client {    public static void main(String[] args) {        try {            Context initial = new InitialContext();            Object objref = initial.lookup("MyPhoneBook");            PhoneBookHome home =                 (PhoneBookHome)PortableRemoteObject.narrow(objref,                                              PhoneBookHome.class);            PhoneBook phonebook = home.create();            Hashtable h = phonebook.lookup("Van H%cke");            for (Enumeration keys = h.keys() ; keys.hasMoreElements() ;) {                String fullname = (String) keys.nextElement();                System.out.println("Name: " + fullname);                System.out.println("Phone: " + (String) h.get(fullname));            }            phonebook.remove();        } catch (Exception ex) {            System.err.println("Caught an unexpected exception!");            ex.printStackTrace();        }    }  }
end example

Stateful session beans

Stateful session beans differ from stateless session beans in that they maintain state across method invocations. They can hold information on behalf of a client and make this information available during method invocations. State is preserved across method calls. Note that maintaining an open database connection as a bean attribute isn’t a good idea; maintaining open connections during the whole life of a bean may not prove efficient. A more scalable approach is to get a connection from the pool whenever needed and return it to the pool when it is no longer required.

As an example, consider a shopping cart for an e-commerce application. Unlike items for sale, orders, and prices, a shopping cart isn’t typically a database object; there won’t be a database table for shopping carts. In fact there is no need to maintain persistent information for a shopping cart for a very long time. Listing 10-3 shows how a very simple shopping cart may be implemented with a stateful session bean. In this example, a bean client can add items to its shopping cart after creating it and then pass the order. Adding items to the shopping cart will actually modify its state, or member attribute, but won’t affect the database. However, ordering the items will imply some interaction with a database, as the order details must be available for processing the order asynchronously.

Listing 10-3: A Stateful Session Bean

start example
// a stateful session bean import java.sql.*; import java.util.Date; import java.util.Vector; import javax.ejb.CreateException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; import javax.ejb.EJBException; import javax.naming.InitialContext; import javax.naming.NamingException; public class ShoppingCartBean implements SessionBean {   private Vector items = new Vector();   public void ejbActivate() {   }   public void ejbRemove() {   }   public void ejbPassivate() {   }   public void ejbCreate () throws CreateException {   }   public void addItem(String item, int quantity) {     Object[] orderedItem = new Object[2];     orderedItem[0] = item;     orderedItem[1] = new Integer(quantity);     items.addElement(orderedItem);   }   public void order(String client) {     Date today = new Date();     String query = "INSERT INTO orders VALUES (?, ?, ?, ?)";     try {       Connection conn = getConnection();       PreparedStatement stmt = conn.prepareStatement(query);       for (int j=0; j<items.size(); j++) {         stmt.setDate(1, today);         stmt.setString(2, client);         stmt.setString(3, (String)((Object[])items.elementAt(j))[0]);         stmt.setInt(4, ((Integer)((Object[])items.elementAt(j))[1]).intValue());         stmt.executeUpdate();       }       stmt.close();       conn.close();     } catch (SQLException e) {       throw new EJBException(e);     }   }   private Connection getConnection() throws SQLException   {     InitialContext initCtx = null;     try {       initCtx = new InitialContext();       DataSource ds = (javax.sql.DataSource)         initCtx.lookup("java:comp/env/jdbc/databasePool");       return ds.getConnection();     } catch(NamingException ne) {       throw new EJBException(ne);     } finally {       try {         if(initCtx != null) initCtx.close();       } catch(NamingException ne) {         throw new EJBException(ne);       }     }   } }
end example



JDBC 3. 0. JAVA Database Connectivity
JDBC 3: Java Database Connectivity
ISBN: 0764548751
EAN: 2147483647
Year: 2002
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net