Bean-Managed Persistence Example


This BMP example illustrates what occurs when the methods of an entity EJB are invoked. The features that are common for all BMP entity beans are that they

  • Implement the EntityBean interface

  • Maintain an EntityContext attribute

  • Retrieve the primary key from the EntityContext

  • Create a connection with the data source

  • Insert a row into the database for ejbCreate()

  • Refresh attributes from the database for ejbLoad()

  • Update a row in the database for ejbStore()

  • Delete a row in the database for ejbRemove()

  • Select rows for ejbFind XXX ()

  • Initialize resources from ejbActivate()

  • Release resources from ejbPassivate()

  • Provide getters and setters for attributes

Creating a Connection with a Data Source

When an entity EJB is created, it establishes a connection with a data source. The connection is used to query, store, and retrieve the persistent data that is being mapped by the entity EJB. As shown in Chapter 13, "Accessing Data Repositories Using JDBC," the connection may be established using the DriverManager directly. Chapter 16, "Managing Java Transactions Using JTA," introduced the DataSource and TxDataSource interfaces as features of the JDBC Optional Package. The DataSource or TxDataSource is located by performing a JNDI lookup on the configured name for the object. This isolation from the JDBC driver further increases portability and database independence. The applicaton obtains the database connection from the DataSource instance. In addition to these two methods of establishing a connection with a data source, Chapter 13 showed the configuration for the JDBC Data Source Factory. The DataSource Factory is an instance of a data source resource bound to the JNDI tree. The entity EJB performs a lookup on the JNDI tree to gain access to this resource.

A resource manager is an object that controls access to an enterprise resource. The JDBC DataSource Factory is used to create a connection to a resource manager. The ejb-jar.xml deployment descriptor specifies the resource reference, as shown in Listing 21.12.

Listing 21.12 The ejb-jar.xml Deployment Descriptor May Contain a Specification for a Resource Reference
 <resource-ref>   <resource-ref-name>jdbc/ExampleDSRef</resource-ref-name>   <res-type>javax.sql.Datasource</res-type>   <res-auth>Container</res-auth>   <res-sharing-scope>Shareable<res-sharing-scope> <resource-ref> 

The weblogic-ejb-jar.xml deployment descriptor specifies the JNDI name bound to the resource connection factory. Listing 21.13 shows the reference descriptor snippet.

Listing 21.13 The weblogic-ejb-jar.xml Deployment Descriptor Specifies the JNDI Name that Is Bound to the Resource Connection Factory
 <reference-descriptor>   <resource-description>     <res-ref-name>jdbc/ExampleDSRef</res-ref-name>     <jndi-name>ExampleDS</jndi-name>   <resource-description> </reference-descriptor> 

With the resource reference specified in the deployment descriptors, the EJB can look up the resource connection factory using JNDI. The code snippet used by the EJB to lookup the resource connection factory to obtain a DataSource is shown in Listing 21.14.

Listing 21.14 The EJB Looks Up the Resource Connection Factory Using JNDI
 InitialContext ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/ExampleDSRef"); Connection con = ds.getConnection(); 

Creating the BookEntityBMPBean

The behavior of an entity EJB is defined by the EntityBean interface. The implementation of the entity bean methods defines the object-relational mapping. The BookEntityBean first shown in Chapter 13 focused on the JDBC API. In Listing 21.15, the focus is turned toward the EntityBean interface as implemented using BMP. As mentioned in the section "Container-Managed Persistence Versus Bean-Managed Persistence," the BMP implementation gives the bean provider full control and flexibility over the connection with the database.

Listing 21.15 An Entity EJB Using BMP Takes Full Control over the Interaction with the Database
 /** * BookEntityBMPBean example of a BMP Entity EJB */ package com.objectmind.BookStore; import java.util.Vector; import java.util.Collection; import javax.ejb.*; import javax.naming.InitialContext; import javax.sql.DataSource; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.DriverManager; import java.sql.Connection; import java.sql.PreparedStatement; /**  * @ejbHome <{BookEntityHome}>  * @ejbRemote <{BookEntity}>  * @ejbPrimaryKey <{BookEntityPK}>  * @ejbTransactionAttribute Required  * @persistent*/ // must implement the EntityBean interface public class BookEntityBMPBean implements EntityBean {     // the WebLogic Server will provide a context     private EntityContext context;     // object attributes     public  String bookID;    // primary key     private String title;     private String author;     private float  price;     public void setEntityContext(EntityContext context)         throws javax.ejb.EJBException {         // save the EntityContext         this.context = context;     }     public void unsetEntityContext()         throws javax.ejb.EJBException {         // clear the EntityContext         context = null;     }     /** ejbActivate is used to initialize any resources     *   required by the bean, files, sockets, etc...     */     public void ejbActivate() throws javax.ejb.EJBException {     }     /** ejbPassivate is used to release any resources used         by the bean     */     public void ejbPassivate() throws javax.ejb.EJBException {     }     /**     * ejbCreate() must be overloaded identical with the create()     * methods of the home interface. The parameter list must match     * the parameter list of the create() method in the home interface.     */     public BookEntityPK ejbCreate(BookEntityVO value)         throws javax.ejb.CreateException,                javax.ejb.EJBException {         bookID = value.getBookID();         title = value.getTitle();         author = value.getAuthor();         price = value.getPrice();         // insert a row into the database containing         // this object's attributes         try {             Connection con = openConnection();             PreparedStatement ps = con.prepareStatement(                 "INSERT INTO books "                 + "( book_id, book_name, book_author, book_price ) "                 + "VALUES ( ?, ?, ? )" );             ps.setString( 1, bookID );             ps.setString( 2, title );             ps.setString( 3, author );             ps.setFloat ( 4, price );             if( ps.executeUpdate() != 1 ) {                 throw new CreateException(                     "Failed to create a row in the database" );             }             ps.close();             // return the new primary key on success             BookEntityPK pk = new BookEntityPK();             pk.bookID = bookID;             return pk;         } catch( Exception x ) {             throw new CreateException( x.getMessage() );         }     }     /**     * ejbPostCreate() must be overloaded identical with the     * ejbCreate() methods. The ejbPostCreate() is automatically     * called after ejbCreate()     */     public void ejbPostCreate(BookEntityVO value)     {         // nothing more to do     }     /**     * ejbRemove() deletes row with matching primary key     */     public void ejbRemove() throws RemoveException {         try {             // always open a new connection             Connection con = openConnection();             PreparedStatement ps = con.prepareStatement(                 "DELETE FROM books  " +                 "WHERE book_id = ?" );             ps.setString( 1, bookID );             if( ps.executeUpdate() != 1 ) {                 throw new CreateException(                     "Failed to delete book with id " + bookID );             }             ps.close();         } catch( Exception x ) {             throw new RemoveException( x.getMessage() );         }     }     public void ejbStore() throws javax.ejb.EJBException {     }     public void ejbLoad() throws javax.ejb.EJBException {     }     // getters and setters for object attributes     public String getBookID(){ return bookID; }     public void setBookID(String param){ this.bookID = param; }     public BookEntityPK ejbFindByPrimaryKey(BookEntityPK pk)         throws javax.ejb.FinderException, javax.ejb.EJBException {             // Write your code here             // refresh this object's attributes by searching the database             // for the primary key             if( pk == null ) {                 throw new FinderException( "primary key cannot be null" );             }             try {                 Connection con = openConnection();                 PreparedStatement ps = con.prepareStatement(                     "SELECT author_id, book_name FROM books " +                     "WHERE book_id = ?" );                 ps.setString( 1, pk.bookID );                 ps.executeQuery();                 ResultSet rs = ps.getResultSet();                 if( rs.next() ) {                     bookID = pk.bookID;                     title = rs.getString( 2 );                 } else {                     throw new FinderException( "Could not find " + pk.bookID );                 }                 ps.close();             } catch( Exception x ) {                 throw new FinderException( x.getMessage() );             }             return pk;         }     public Collection ejbFindBooksByAuthor(String author)         throws javax.ejb.FinderException,                javax.ejb.EJBException {         PreparedStatement ps = null;         try {             Connection con = openConnection();             ps = con.prepareStatement(                 "SELECT book_id FROM books " +                 "WHERE author = ?" );             ps.setString( 1, author );             ResultSet rs = ps.executeQuery();             Vector books = new Vector();             while( rs.next() ) {                 BookEntityPK key = new BookEntityPK();                 key.bookID = rs.getString( 1 );             }             return books;         } catch( Exception x ) {             throw new FinderException( x.getMessage() );         }         finally {             closePS( ps );         }     }     public BookEntityVO getBookData(){         BookEntityVO value = new BookEntityVO();         value.setBookID( bookID );         value.setAuthor( author );         value.setTitle( title );         value.setPrice( price );         return value;     }     public void setBookData(BookEntityVO value) {         bookID = value.getBookID();         author = value.getAuthor();         title = value.getTitle();         price = value.getPrice();     }     public String getTitle(){ return title; }     public String getAuthor(){ return author; }     public double getPrice(){ return price; }     public void setPrice( float value ) {         price = value;         //update database record                 PreparedStatement ps = null;         try {             Connection con = openConnection();             BookEntityPK key =                 (BookEntityPK)context.getPrimaryKey();             ps = con.prepareStatement(                 "UPDATE books " +                 "set book_price = ? " +                 "WHERE book_id = ?" );             ps.setFloat( 1, value );             ps.setString( 2, key.bookID );             int rows = ps.executeUpdate();             if( rows != 1 ) {                 throw new EJBException(                     "setPrice failed to update database" );             }         } catch( Exception x ) {             throw new EJBException( x.getMessage() );         }         finally {             closePS( ps );         }     }     // get Connection from DataSource     public Connection openConnection() throws EJBException {         try {             InitialContext ic = new InitialContext();             DataSource ds = (DataSource)ic.lookup("MyDataSource");             return ds.getConnection();         }         catch( Exception x ) {             throw new EJBException( x.getMessage() );         }     }     private void closePS( PreparedStatement ps )     {         try         {             if( ps != null )                 ps.close();         }         catch( SQLException x ) {         }     } } 

Creating the BMP Style Deployment Descriptor

The ejb-jar.xml deployment descriptor for the BookEntityBMPBean is shown in Listing 21.16. The JAR file contains a single deployment descriptor in the META-INF directory that defines the deployment characteristics for all the EJBS in the JAR.

Listing 21.16 The Deployment Descriptor for a BMP Entity Bean Specifies the Names of the Interfaces for the EJB Class and Defines the Transaction Attributes
 <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'> <!-- Generated XML! --><ejb-jar> <ejb-jar>   <enterprise-beans>     <entity>       <ejb-name>BookEntityBMPBean</ejb-name>       <home>BookEntityHome</home>       <remote>BookEntity</remote>       <local-home>BookEntityLocalHome</local-home>       <local>BookEntityLocal</local>       <ejb-class>BookEntityBMPBean</ejb-class>       <persistence-type>Bean</persistence-type>       <prim-key-class>BookEntityPK</prim-key-class>       <reentrant>False</reentrant>     </entity>   </enterprise-beans>   <assembly-descriptor>     <container-transaction>       <method>         <ejb-name>BookEntityBMPBean</ejb-name>         <method-name>*</method-name>       </method>       <trans-attribute>Required</trans-attribute>     </container-transaction>   </assembly-descriptor> </ejb-jar> 


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