Container-Managed Relationship Example


The Container-Managed Relationship is used when a composition relationship exists between CMP entity beans. This example is a shopping cart that contains the books that have been selected for purchase. The ShoppingCart requires persistent storage to allow its life cycle to span system shutdowns and crashes. The ShoppingCart will be implemented as a CMP entity EJB. The books in the shopping cart establish a one-to-many relationship between the ShoppingCart and the BookEntityCMPBean . The local interfaces of the BookEntity will be used by the ShoppingCart for improved efficiency and higher performance.

Creating the ShoppingCart Remote Interface

The remote interface shown in Listing 21.18 allows books to be added to the cart and all books to be retrieved from the cart as an array. This example uses the BookEntityVO as a convenient way to pass all attributes in a single value object parameter. The addBook() method is overloaded to pass an instance of a BookEntity as the parameter.

Listing 21.18 Remote Interface for the ShoppingCart
 /** * Remote interface for the ShoppingCart */ package com.objectmind.ShoppingCart; import com.objectmind.BookStore.*; import java.rmi.RemoteException; import javax.ejb.EJBObject; import javax.ejb.CreateException; import javax.ejb.FinderException; import javax.naming.NamingException; public interface ShoppingCart extends EJBObject {     public void addBook(BookEntityVO book)         throws NamingException, CreateException,                RemoteException, FinderException;     public void addBook(BookEntity book)         throws NamingException, CreateException,                RemoteException;     public BookEntityVO[] getAllBooks()         throws RemoteException; } 

Creating the ShoppingCart Home Interface

The ShoppingCartHome , shown in Listing 21.19, creates a reference to a ShoppingCart for the given primary key. The finder methods find a ShoppingCart by matching a primary key and also find all instances of ShoppingCart .

Listing 21.19 Sample Remote Home Interface for ShoppingCart
 /** * ShoppingCartHome is the home interface for the ShoppingCart. */ package com.objectmind.ShoppingCart; import java.rmi.RemoteException; import java.util.Collection; import javax.ejb.EJBHome; import javax.ejb.CreateException; import javax.ejb.FinderException; public interface ShoppingCartHome extends EJBHome {     /**     * Create method for ShoppingCart     * @return BookEntity EJBObject     */     public ShoppingCart create()         throws CreateException, RemoteException;     /**     * findByPrimaryKey is required for all entity beans     * @param  primaryKey  Integer     * @return ShoppingCart  object matching primary key     */     public ShoppingCart findByPrimaryKey(         Integer primaryKey )         throws FinderException, RemoteException;     /**     * Finder method to create a list of all shopping carts     * @return collection of BookEntity objects in a Vector     */     public Collection findAll()       throws FinderException, RemoteException; } 

Creating the ShoppingCart CMP Entity Bean

The attributes of the ShoppingCart are its primary key and a collection of books. The primary key is the cartId of type java.lang.String while books are represented through a java.util.Collection . Listing 21.20 shows the CMP entity bean implementation of the shopping cart.

Listing 21.20 The ShoppingCartCMPBean Is Implemented As an Abstract Class That Uses Container-Managed Persistence
 /** * ShoppingCartCMPBean example of a CMP Entity EJB */ package com.objectmind.ShoppingCart; import com.objectmind.BookStore.*; import java.util.Collection; import javax.ejb.EntityBean; import javax.ejb.EntityContext; import javax.ejb.EJBException; import javax.ejb.CreateException; import javax.ejb.FinderException; import javax.ejb.RemoveException; import java.rmi.RemoteException; import javax.naming.NamingException; import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; import java.sql.SQLException; import java.sql.DriverManager; import java.sql.Connection; import java.sql.PreparedStatement; /**  * @ejbHome <{ShoppingCartHome}>  * @ejbRemote <{ShoppingCart}>  * @ejbPrimaryKey <{ShoppingCartPK}>  * @ejbTransactionAttribute Required  * @persistent*/ // must implement the EntityBean interface public abstract class ShoppingCartCMPBean implements EntityBean {     // the WebLogic Server will provide a context     private EntityContext ctx;     public void setEntityContext(EntityContext context)         throws EJBException {         // save the EntityContext         ctx = context;     }     public void unsetEntityContext()         throws EJBException {         // clear the EntityContext         ctx = null;     }     /**     * abstract setters and getters for container-managed fields     */     abstract public Integer getCartID();     abstract public void   setCartID(Integer id);     abstract public Integer getCustomerID();     abstract public void    setCustomerID( Integer id );     abstract public Collection getBooks();     abstract public void   setBooks(Collection books);     /**     * stubs for container-managed behavior     */     public void ejbActivate() throws javax.ejb.EJBException{     }     public void ejbPassivate() throws javax.ejb.EJBException {     }     public void ejbRemove() throws RemoveException {     }     public void ejbStore() throws javax.ejb.EJBException {     }     public void ejbLoad() throws javax.ejb.EJBException {     }     /**     * initialize the bean from the value object     */     public Integer ejbCreate() {         return null;     }     public void ejbPostCreate() {     }     public void addBook(BookEntityVO bookData)         throws NamingException, CreateException, FinderException     {         try         {             // use JNDI to lookup the Home interface for Book             Context jndiContext = new InitialContext();             BookEntityHome bookHome =                 (BookEntityHome)jndiContext.lookup("cmp.BookEntity");             // make sure the book is in stock before adding             // it to the shopping cart             BookEntity book =                 bookHome.findBookByTitle( bookData.getTitle() );             // create a new Book entity             book = bookHome.create(bookData);             // add the Book reference to our book list             Collection books = getBooks();             books.add(book);         }         catch( FinderException x )         {             ctx.setRollbackOnly();             throw x;         }         catch( RemoteException x )         {         }     }     public void addBook(BookEntity book)         throws NamingException, CreateException     {         // add the Book reference to our book list         Collection books = getBooks();         books.add(book);     }     public BookEntityVO[] getAllBooks()     {         Collection books = getBooks();         return (BookEntityVO[])books.toArray();     } } 

The ShoppingCart Primary Key

The weblogic-cmp-rdbms-jar.xml deployment descriptor for the ShoppingCart specifies automatic key generation for the primary key. The primary key class for the ShoppingCart is therefore, java.lang.Integer . Refer to the ejb-jar.xml shown in Listing 21.22 to see the specification for the <prim-key-class> for the ShoppingCart . Also, refer to Listing 21.24 to see the specification for <automatic-key-generation> in the weblogic-cmp-rdbms-jar.xml descriptor. These topics are explained in the "Deployment on WebLogic Server" section later in this chapter.

Testing the Book Store

The client of an entity EJB is typically either a session EJB, a JSP or a servlet. The Customer class, shown in Listing 21.21, is provided here as an example to test the API for the BookEntity and ShoppingCart entity EJBs. The customer creates an instance of the home interface for the BookEntity . This BookEntityHome object is used to invoke the finder methods for books. A reference to a ShoppingCart is obtained by looking up the ShoppingCartHome and using it to create a ShoppingCart . The addBook() method of ShoppingCart is invoked when a book is purchased.

Listing 21.21 The Customer Class Tests the API for the BookEntity and ShoppingCart Entity EJBs
 /**  * BookStore customer will purchase books by  * adding them to a shopping cart.  */ package com.objectmind.BookStore; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.ejb.CreateException; import javax.ejb.DuplicateKeyException; import java.rmi.RemoteException; import com.objectmind.ShoppingCart.*; public class Customer {     // object attributes     private Context         context;     private ShoppingCart    cart;     private BookEntityHome    bookFinder;     private BookEntityVO    bookData;     public Customer( String title, String author, float price, String id )         throws NamingException, CreateException, RemoteException     {         // create the JNDI context         context = createJNDIContext();         // create the book entity home to         // use its finder methods for books         bookFinder = createBookFinder();         bookData = new BookEntityVO();         bookData.setTitle( title );         bookData.setAuthor( author );         bookData.setBookID( id );         bookData.setPrice( price );         // create a sample book         try         {             bookFinder.create( bookData );         }         catch( RemoteException x )         {             // the DuplicateKeyException is nested as an RemoteException             System.err.println( "Book already exists" );         }         catch( Exception x )         {             System.err.println( x.getMessage() );         }         // create a shopping cart         cart = createShoppingCart();     }     private Context createJNDIContext()         throws NamingException     {         Hashtable env = new Hashtable();         env.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");         env.put(Context.PROVIDER_URL,"t3://localhost:7001");         Context context = new InitialContext( env );         return context;     }     public BookEntityHome createBookFinder()         throws NamingException, CreateException     {         // use JNDI to lookup the Home interface for Book         BookEntityHome bookHome =             (BookEntityHome)context.lookup("cmp.BookEntity");         return bookHome;     }     public ShoppingCart createShoppingCart()         throws NamingException, CreateException, RemoteException     {         // use JNDI to lookup the Home interface for Book         ShoppingCartHome cartHome =             (ShoppingCartHome)context.lookup("cmp.ShoppingCart");         ShoppingCart cart = cartHome.create();         return cart;     }     public void purchase()         throws Exception     {         cart.addBook( bookData );         // if no exceptions were thrown...         System.out.println( "Thank you for purchasing " + bookData.getTitle() );     }     /**      * Main method to unit test the customer API      */     public static void main(String[] args)     {         // check command line args         if( args.length != 4 )         {             System.err.println(                 "usage: Customer <title> <author> <price> <bookID>");             System.exit( -1 );         }         try         {             String title = args[0];             String author = args[1];             float price = Float.valueOf( args[2] ).floatValue();             String bookID = args[3];             Customer customer = new Customer(                 title, author, price, bookID );             customer.purchase();         }         catch( Exception x )         {             System.err.println( "Failed to purchase \"" + args[0] + "\"" );         }     } } 

Creating the Deployment Descriptor

The ShoppingCart uses CMP for the cartID field and CMR for the one-to-many relationship with books. All methods of ShoppingCart are specified to use the Required transaction type for CMT. These specifications are defined in the ejb-jar.xml deployment descriptor shown in Listing 21.22.

Listing 21.22 The Deployment Descriptor Provides the Specification for the Persistence and Transactions Provided by the Container
[View full width]
 <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' graphics/ccc.gif 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'> <!-- Generated XML! --> <ejb-jar>   <enterprise-beans>     <entity>       <ejb-name>ShoppingCart</ejb-name>       <home>com.objectmind.ShoppingCart.ShoppingCartHome</home>       <remote>com.objectmind.ShoppingCart.ShoppingCart</remote>       <ejb-class>com.objectmind.ShoppingCart.ShoppingCartCMPBean</ejb-class>       <persistence-type>Container</persistence-type>       <prim-key-class>java.lang.Integer</prim-key-class>       <reentrant>False</reentrant>       <cmp-version>2.x</cmp-version>       <abstract-schema-name>ShoppingCartSchema</abstract-schema-name>       <cmp-field>         <field-name>cartID</field-name>       </cmp-field>       <cmp-field>         <field-name>customerID</field-name>       </cmp-field>       <primkey-field>cartID</primkey-field>       <query>         <query-method>           <method-name>findAll</method-name>           <method-params>           </method-params>         </query-method>         <ejb-ql><![CDATA[SELECT OBJECT(s) FROM ShoppingCartSchema                    AS s]]></ejb-ql>       </query>     </entity>     <entity>       <ejb-name>BookStore</ejb-name>       <home>com.objectmind.BookStore.BookEntityHome</home>       <remote>com.objectmind.BookStore.BookEntity</remote>       <local-home>com.objectmind.BookStore.BookEntityLocalHome</local-home>       <local>com.objectmind.BookStore.BookEntityLocal</local>       <ejb-class>com.objectmind.BookStore.BookEntityCMPBean</ejb-class>       <persistence-type>Container</persistence-type>       <prim-key-class>com.objectmind.BookStore.BookEntityPK</prim-key-class>       <reentrant>False</reentrant>       <cmp-version>2.x</cmp-version>       <abstract-schema-name>BookstoreSchema</abstract-schema-name>       <cmp-field>         <field-name>bookID</field-name>       </cmp-field>       <cmp-field>         <field-name>title</field-name>       </cmp-field>       <cmp-field>         <field-name>author</field-name>       </cmp-field>       <cmp-field>         <field-name>price</field-name>       </cmp-field>       <primkey-field>bookID</primkey-field>       <query>         <query-method>           <method-name>findBookByTitle</method-name>           <method-params>             <method-param>java.lang.String</method-param>           </method-params>         </query-method>         <ejb-ql>           <![CDATA[SELECT OBJECT(a) FROM BookstoreSchema AS a WHERE a.title = ?1]]>         </ejb-ql>       </query>       <query>         <query-method>           <method-name>findBooksByAuthor</method-name>           <method-params>             <method-param>java.lang.String</method-param>           </method-params>         </query-method>         <ejb-ql><![CDATA[SELECT OBJECT(a) FROM BookstoreSchema AS a WHERE a.author = ?1]]>< graphics/ccc.gif /ejb-ql>       </query>     </entity>   </enterprise-beans>   <relationships>     <ejb-relation>       <ejb-relation-name>ShoppingCart-Book</ejb-relation-name>       <ejb-relationship-role>         <ejb-relationship-role-name>ShoppingCart-Has-Books</ejb-relationship-role-name>         <multiplicity>many</multiplicity>                 <relationship-role-source>           <ejb-name>BookStore</ejb-name>         </relationship-role-source>         <cmr-field>           <cmr-field-name>cart</cmr-field-name>         </cmr-field>       </ejb-relationship-role>       <ejb-relationship-role>         <ejb-relationship-role-name>Book-Has-ShoppingCart</ejb-relationship-role-name>         <multiplicity>one</multiplicity>                 <relationship-role-source>           <ejb-name>ShoppingCart</ejb-name>         </relationship-role-source>         <cmr-field>           <cmr-field-name>books</cmr-field-name>           <cmr-field-type>java.util.Collection</cmr-field-type>         </cmr-field>       </ejb-relationship-role>     </ejb-relation>   </relationships>   <assembly-descriptor>     <container-transaction>       <method>         <ejb-name>ShoppingCart</ejb-name>         <method-name>*</method-name>       </method>       <trans-attribute>Required</trans-attribute>     </container-transaction>     <container-transaction>       <method>         <ejb-name>BookStore</ejb-name>         <method-name>*</method-name>       </method>       <trans-attribute>Required</trans-attribute>     </container-transaction>  </assembly-descriptor> 


BEA WebLogic Platform 7
BEA WebLogic Platform 7
ISBN: 0789727129
EAN: 2147483647
Year: 2003
Pages: 360

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