BMP Entity Bean

Java Primer
Incremental J2EE
by Vince Huston
Listing 9. BMP Entity Bean.


// Purpose.  BMP Entity Bean

import java.util.*;
import java.rmi.RemoteException;
import javax.ejb.*;
import java.sql.*;

interface RIItem extends EJBObject {
   public String getSummary() throws RemoteException;
   public int    order()      throws RemoteException;
}

interface HIItem extends EJBHome {
   RIItem create( Integer pk, String nm, int pr ) throws RemoteException, CreateException;
   Collection findAllInstances()                  throws RemoteException, FinderException;
   RIItem     findByPrimaryKey( Integer pk )      throws RemoteException, FinderException;
}

public class ItemImpl implements EntityBean {
   transient private EntityContext context;
   private int    id;
   private String name;
   private int    price;
   private int    numSold;

   private Connection getConnection() throws SQLException {
      javax.sql.DataSource ds = null;
      try {
      Object obj = new javax.naming.InitialContext().lookup( "jdbc/Cloudscape" );
      ds = (javax.sql.DataSource) javax.rmi.PortableRemoteObject.narrow(
                                           obj, javax.sql.DataSource.class );
      } catch (javax.naming.NamingException ex) { ex.printStackTrace(); }
      return ds.getConnection( "guest", "guest123" );
   }

   public Integer ejbCreate( Integer pk, String nm, int pr ) throws CreateException {
      id = pk.intValue();
      name = nm;
      price = pr;
      numSold = 0;
      System.out.println( "ItemImpl ejbCreate: " + id );

      Connection        conn = null;
      PreparedStatement ps   = null;
      try {
         conn = getConnection();
         ps = conn.prepareStatement( "INSERT INTO ItemImplTable VALUES(?,?,?,?)" );
         ps.setInt(    1, id );
         ps.setString( 2, name );
         ps.setInt(    3, price );
         ps.setInt(    4, numSold );
         if (ps.executeUpdate() != 1)
            throw new CreateException( "failed to add DB record" );
         return pk;
      } catch (SQLException ex) {
         throw new CreateException( ex.getMessage() );
      } finally {
         try {
            if (ps   != null) ps.close();
            if (conn != null) conn.close();
         } catch (SQLException ex) { ex.printStackTrace(); }
   }  }

   public void ejbPostCreate( Integer pk, String nm, int pr ) {
      System.out.println( "ItemImpl ejbPostCreate: " + id );
   }

   public String getSummary() {
      return name + " $" + price + " ... " + numSold;
   }
   public int order() {
      numSold++;
      return price;
   }


   private void loadUsingPK( Integer id ) throws RemoteException, FinderException {
      Connection        conn = null;
      PreparedStatement ps   = null;
      ResultSet         rs   = null;
      try {
         conn = getConnection();
         ps = conn.prepareStatement(
            "SELECT name, price, numSold FROM ItemImplTable WHERE id=?" );
         ps.setInt( 1, id.intValue() );
         rs = ps.executeQuery();
         if (rs.next()) {
            this.id = id.intValue();
            name    = rs.getString( "name" );
            price   = rs.getInt( "price"   );
            numSold = rs.getInt( "numSold" );
         } else
            throw new ObjectNotFoundException( "cannot find " + id.intValue() );
      } catch (SQLException ex) {
         throw new FinderException( ex.getMessage() );
      } finally {
         try {
            if (rs   != null) rs.close();
            if (ps   != null) ps.close();
            if (conn != null) conn.close();
         } catch (SQLException ex) { ex.printStackTrace(); }
   }  }


   public Integer ejbFindByPrimaryKey( Integer pk )
                   throws FinderException, RemoteException {
      loadUsingPK( pk );
      System.out.println( "ItemImpl ejbFindByPrimaryKey: " + pk.intValue() );
      return pk;
   }

   public Collection ejbFindAllInstances()
                   throws FinderException, RemoteException {
      Connection        conn = null;
      PreparedStatement ps   = null;
      ResultSet         rs   = null;
      try {
         conn = getConnection();
         ps = conn.prepareStatement( "SELECT id FROM ItemImplTable" );
         rs = ps.executeQuery();
         ArrayList list = new ArrayList();
         while (rs.next())
            list.add( new Integer( rs.getInt( "id" ) ) );
         System.out.println( "ItemImpl ejbFindAllInstances: returning "
            + list.size() + " items" );
         return list;
      } catch (SQLException ex) {
         throw new FinderException( ex.getMessage() );
      } finally {
         try {
            if (rs   != null) rs.close();
            if (ps   != null) ps.close();
            if (conn != null) conn.close();
         } catch (SQLException ex) { ex.printStackTrace(); }
   }  }

   // from javax.ejb.SessionBean and EntityBean interfaces
   public void ejbRemove() throws RemoteException {
      System.out.println( "ItemImpl ejbRemove: " + id );

      Connection        conn = null;
      PreparedStatement ps   = null;
      try {
         conn = getConnection();
         ps = conn.prepareStatement( "DELETE FROM ItemImplTable WHERE id=?" );
         ps.setInt( 1, id );
         if (ps.executeUpdate() != 1)
            throw new RemoteException( "failed to remove " + name );
      } catch (SQLException ex) {
         throw new RemoteException( ex.getMessage() );
      } finally {
         try {
            if (ps   != null) ps.close();
            if (conn != null) conn.close();
         } catch (SQLException ex) { ex.printStackTrace(); }
   }  }

   public void ejbActivate() {
      id = ((Integer)context.getPrimaryKey()).intValue();
      System.out.println( "ItemImpl ejbActivate: " + id );
   }
   public void ejbPassivate() { System.out.println( "ItemImpl ejbPassivate: " + id ); }
   public void setEntityContext( EntityContext ctx ) {
      System.out.println( "ItemImpl setEntityContext: " + id ); 
      context = ctx;
   }

   // from javax.ejb.EntityBean interface
   public void ejbLoad() throws RemoteException {
      System.out.println( "ItemImpl ejbLoad: " + id );
      try {
         Integer pk = (Integer) context.getPrimaryKey();
         loadUsingPK( pk );
      } catch (FinderException ex) {
         throw new RemoteException( ex.getMessage() );
   }  }

   public void ejbStore() throws RemoteException {
      System.out.println( "ItemImpl ejbStore: " + id );

      Connection        conn = null;
      PreparedStatement ps   = null;
      try {
         conn = getConnection();
         ps = conn.prepareStatement(
            "UPDATE ItemImplTable SET name=?, price=?, numSold=? where id=?" );
         ps.setString( 1, name );
         ps.setInt(    2, price );
         ps.setInt(    3, numSold );
         ps.setInt(    4, id );
         if (ps.executeUpdate() != 1)
            throw new RemoteException( "failed to update DB record" );
      } catch (SQLException ex) {
         throw new RemoteException( ex.getMessage() );
      } finally {
         try {
            if (ps   != null) ps.close();
            if (conn != null) conn.close();
         } catch (SQLException ex) { ex.printStackTrace(); }
   }  }

   public void unsetEntityContext() {
      System.out.println( "ItemImpl setEntityContext: " + id );
      context = null;
}  }



import java.util.*;
import java.rmi.RemoteException;
import javax.rmi.*;
import javax.ejb.*;
import javax.naming.*;

interface RIStore extends EJBObject {
   Collection getItems()            throws RemoteException;
   void       selectItem( int num ) throws RemoteException;
   String     placeOrder()          throws RemoteException;
}

interface HIStore extends EJBHome {
   public RIStore create() throws java.rmi.RemoteException, CreateException;
}

public class StoreImpl implements SessionBean {
   private ArrayList  itemList   = new ArrayList();
   private ArrayList  theChoices = new ArrayList();
   private SessionContext context;

   public void ejbCreate() {
      System.out.println( "ejbCreate:" );
      try {
         InitialContext ic = new InitialContext();
         Object obj = ic.lookup( "ItemHome" );
         HIItem itemHome = (HIItem) PortableRemoteObject.narrow( obj, HIItem.class );
         Collection col = itemHome.findAllInstances();
         if (col.size() > 0)
            for (Iterator it = col.iterator(); it.hasNext(); )
               itemList.add( it.next() );
         else {
            itemList.add( itemHome.create( new Integer(1), "Design Patterns by GOF .....", 35 ));
            itemList.add( itemHome.create( new Integer(2), "Using UML and Patterns .....", 30 ));
            itemList.add( itemHome.create( new Integer(3), "C++ for Deadend Careers .... ", 5 ));
            itemList.add( itemHome.create( new Integer(4), "Java for Resume Inflation ..", 10 ));
            itemList.add( itemHome.create( new Integer(5), "Practical Java .............", 20 ));
         }
      } catch (NamingException ex) { ex.printStackTrace();
      } catch (FinderException ex) { ex.printStackTrace();
      } catch (CreateException ex) { ex.printStackTrace();
      } catch (RemoteException ex) { ex.printStackTrace();
   }  }
   public Collection getItems() {
      Collection summary = new ArrayList();
      try {
         for (Iterator it = itemList.iterator(); it.hasNext(); )
            summary.add( ((RIItem)it.next()).getSummary() );
      } catch (RemoteException ex) { ex.printStackTrace(); }
      System.out.println( "\nreturning " + summary.size() + " items to client" );
      return summary;
   }
   public void selectItem( int num ) {
      theChoices.add( new Integer( num ) );
   }
   public String placeOrder() {
      StringBuffer sb = new StringBuffer();
      RIItem ele;
      String str;
      int    totalBill = 0;
      System.out.println();
      sb.append( "The following items were ordered:\n" );
      try {
         for (Iterator it = theChoices.iterator(); it.hasNext(); ) {
            ele = (RIItem) itemList.get( ((Integer)it.next()).intValue() );
            totalBill += ele.order();
            str = ele.getSummary();
            System.out.println( str );
            sb.append( "   " );
            sb.append( str );
            sb.append( '\n' );
         }
      } catch (RemoteException ex) { ex.printStackTrace(); }
      sb.append( "Total bill is $" + totalBill + "\n" );
      System.out.println( "returning " + theChoices.size()
         + " orders to client, bill is $" + totalBill + "\n" );
      return sb.toString();
   }

   // from javax.ejb.SessionBean interface
   public void ejbRemove()    { System.out.println( "ejbRemove:" ); }
   public void ejbActivate()  { System.out.println( "ejbActivate:" ); }
   public void ejbPassivate() { System.out.println( "ejbPassivate:" ); }
   public void setSessionContext( SessionContext ctx ) {
      System.out.println( "setSessionContext:" ); 
      context = ctx;
}  }

/***************
setSessionContext:
ejbCreate:
ItemImpl setEntityContext: 0
ItemImpl ejbFindAllInstances: returning 0 items
ItemImpl ejbCreate: 1
ItemImpl ejbPostCreate: 1
ItemImpl setEntityContext: 0
ItemImpl ejbCreate: 2
ItemImpl ejbPostCreate: 2
ItemImpl setEntityContext: 0
ItemImpl ejbCreate: 3
ItemImpl ejbPostCreate: 3
ItemImpl setEntityContext: 0
ItemImpl ejbCreate: 4
ItemImpl ejbPostCreate: 4
ItemImpl setEntityContext: 0
ItemImpl ejbCreate: 5
ItemImpl ejbPostCreate: 5

returning 5 items to client

Design Patterns by GOF ..... $35 ... 1
Using UML and Patterns ..... $30 ... 1
Design Patterns by GOF ..... $35 ... 2
returning 3 orders to client, bill is $100

setSessionContext:
ejbCreate:
ItemImpl setEntityContext: 0
ItemImpl ejbFindAllInstances: returning 5 items

returning 5 items to client

Using UML and Patterns ..... $30 ... 2
C++ for Deadend Careers ....  $5 ... 1
Using UML and Patterns ..... $30 ... 3
returning 3 orders to client, bill is $65

setSessionContext:
ejbCreate:
ItemImpl ejbFindAllInstances: returning 5 items

returning 5 items to client
***************/



import java.util.*;
import java.io.*;
import javax.rmi.*;
import javax.naming.*;
import javax.ejb.CreateException;

public class StoreClient {
   public static void main( String[] args ) {
      BufferedReader in = new BufferedReader(
                             new InputStreamReader( System.in ) );
      int choice;
      try {
         InitialContext ic = new InitialContext();
         Object     obj       = ic.lookup( "StoreHome" );
         System.out.println( "obj.getName is " + obj.getClass().getName() );
         System.out.println( "obj instanceof HIStore is " + (obj instanceof HIStore) );
         HIStore    storeHome = (HIStore) PortableRemoteObject.narrow( obj, HIStore.class );
         RIStore    theStore  = storeHome.create();
         Collection theItems  = theStore.getItems();

         System.out.println( "Select from (0 when done):" );
         Iterator it = theItems.iterator();
         for (int i=1; it.hasNext(); i++)
            System.out.println( "   " + i + " - " + it.next() );

         while (true) {
            System.out.print( "Choice: " );
            if ((choice = Integer.parseInt( in.readLine() )) == 0) break;
            theStore.selectItem( choice-1 );
         }

         System.out.println( theStore.placeOrder() );

      } catch (NamingException ex ) { ex.printStackTrace();
      } catch (CreateException ex ) { ex.printStackTrace();
      } catch (IOException ex )     { ex.printStackTrace();
}  }  }

/***************
D:\j2ee\bmp> java StoreClient
obj.getName is _HIStore_Stub
obj instanceof HIStore is true
Select from (0 when done):
   1 - Design Patterns by GOF ..... $35 ... 0
   2 - Using UML and Patterns ..... $30 ... 0
   3 - C++ for Deadend Careers ....  $5 ... 0
   4 - Java for Resume Inflation .. $10 ... 0
   5 - Practical Java ............. $20 ... 0
Choice: 1
Choice: 2
Choice: 1
Choice: 0
The following items were ordered:
   Design Patterns by GOF ..... $35 ... 1
   Using UML and Patterns ..... $30 ... 1
   Design Patterns by GOF ..... $35 ... 2
Total bill is $100


D:\j2ee\bmp> java StoreClient
obj.getName is _HIStore_Stub
obj instanceof HIStore is true
Select from (0 when done):
   1 - Design Patterns by GOF ..... $35 ... 2
   2 - Using UML and Patterns ..... $30 ... 1
   3 - C++ for Deadend Careers ....  $5 ... 0
   4 - Java for Resume Inflation .. $10 ... 0
   5 - Practical Java ............. $20 ... 0
Choice: 2
Choice: 3
Choice: 2
Choice: 0
The following items were ordered:
   Using UML and Patterns ..... $30 ... 2
   C++ for Deadend Careers ....  $5 ... 1
   Using UML and Patterns ..... $30 ... 3
Total bill is $65


D:\j2ee\bmp> java StoreClient
obj.getName is _HIStore_Stub
obj instanceof HIStore is true
Select from (0 when done):
   1 - Design Patterns by GOF ..... $35 ... 2
   2 - Using UML and Patterns ..... $30 ... 3
   3 - C++ for Deadend Careers ....  $5 ... 1
   4 - Java for Resume Inflation .. $10 ... 0
   5 - Practical Java ............. $20 ... 0
Choice:
***************/