Sams Teach Yourself BEA WebLogic Server 7.0 in 21 Days

For your sample program today, you will use and modify the restaurant application that you have built over the past few days. Yesterday, you used CMP to build the entity bean. To help you understand the differences between using BMP and using CMP to build an entity bean, today you will build the same ItemBean using BMP. Take a look at Listing 13.1, which shows the source code of the ItemBean.

Listing 13.1 ItemBean.java

/****************************************************************************** * Class Name : ItemBean.java * Description : Bean Class for the ItemBean bean. * Implements the methods defined in the Home and Remote * interfaces. These methods are called by the Chef bean. * @author Mandar S. Chitnis, Lakshmi AM, Pravin S. Tiwari. @version 1.1 * Copyright (c) by Sams Publishing. All Rights Reserved. ******************************************************************************/ package com.sams.learnweblogic7.ejb.bmp; import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.DuplicateKeyException; import javax.ejb.EJBException; import javax.ejb.EntityBean; import javax.ejb.EntityContext; import javax.ejb.FinderException; import javax.ejb.NoSuchEntityException; import javax.ejb.ObjectNotFoundException; import javax.ejb.RemoveException; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; public class ItemBean implements EntityBean { private EntityContext ctx; public int itemId; public String itemDesc; public String itemTemperature; public String itemTaste; public String itemIngredients; public String itemServingSize; public void setEntityContext(EntityContext ctx) { System.out.println( "setEntityContext called "+System.currentTimeMillis()); this.ctx = ctx; } public void unsetEntityContext() { System.out.println("ItemBean.unsetEntityContext"+System.currentTimeMillis()); this.ctx = null; } /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbActivate() { System.out.println("ItemBean.ejbActivate"+System.currentTimeMillis()); } /** * This method is required by the EJB Specification, * but is not used by this example. * */ public void ejbPassivate() { System.out.println("ItemBean.ejbPassivate"+System.currentTimeMillis()); } public void ejbLoad() { System.out.println("ItemBean.ejbLoad"+System.currentTimeMillis()); Connection conn = null; PreparedStatement prepStmt = null; try{ conn = getConnection(); prepStmt = conn.prepareStatement("Select item_desc,item_taste, item_temperature,item_ingredients, item_serving_size from item where item_id=?"); ItemPK key = (ItemPK)ctx.getPrimaryKey(); itemId = key.itemId; prepStmt.setInt(1, itemId); ResultSet rs = prepStmt.executeQuery(); while(rs.next()){ itemDesc = rs.getString("item_desc"); itemTaste = rs.getString("item_taste"); itemTemperature = rs.getString("item_temperature"); itemIngredients = rs.getString("item_ingredients"); itemServingSize = rs.getString("item_serving_size"); } System.out.println("End of ejb load"+System.currentTimeMillis()); } catch(Exception e){ System.out.println("Error occured in ejb Load"); e.printStackTrace(); throw new EJBException("SQL update failed. ejbLoad( ) failed"); } finally{ try{ if(conn != null){ conn.close(); System.out.println( "closed connection in ejb load" +System.currentTimeMillis()); } } catch(Exception e){ e.printStackTrace(); } } } /** * Sets the EJBean's modified flag to false. * set to false to "reset" the variable for the next transaction. * */ public void ejbStore() { System.out.println("ItemBean.ejbStore"+System.currentTimeMillis()); Connection conn = null; PreparedStatement prepStmt = null; try{ conn = getConnection(); prepStmt = conn.prepareStatement("Update Item set item_desc = ?, item_taste = ?, item_temperature = ?, item_ingredients = ?, item_serving_size = ? where item_id=?"); prepStmt.setString(1, itemDesc); prepStmt.setString(2, itemTaste); prepStmt.setString(3, itemTemperature); prepStmt.setString(4, itemIngredients); prepStmt.setString(5, itemServingSize); prepStmt.setInt(6, itemId); if(prepStmt.executeUpdate() != 1) throw new EJBException("SQL update failed. ejbStore( ) failed"); System.out.println("End of ejb Store"+System.currentTimeMillis()); } catch(Exception e){ System.out.println("Error in EJB Store method"); e.printStackTrace(); } finally{ try{ if(conn != null){ conn.close(); System.out.println( "connection closed in ejb store" +System.currentTimeMillis()); } } catch(Exception e){ e.printStackTrace(); } } } /** * This method is required by the EJB Specification, * but is not used by this example. * * @exception javax.ejb.RemoveException * if the EJBean does not allow removing the EJBean */ public void ejbRemove() throws RemoveException { System.out.println("ItemBean.ejbRemove "+System.currentTimeMillis()); Connection conn = null; PreparedStatement prepStmt = null; try{ conn = getConnection(); prepStmt = conn.prepareStatement("Delete from Item where item_id = ?"); prepStmt.setInt(1, itemId); prepStmt.executeUpdate(); System.out.println("end of ejb Remove"+System.currentTimeMillis()); } catch(Exception e){ System.out.println("Error in ejb Remove"); e.printStackTrace(); } finally{ try{ if(conn != null){ conn.close(); System.out.println( "connection closed in ejb remove" +System.currentTimeMillis()); } } catch(Exception e){ e.printStackTrace(); } } } /** * This method corresponds to the create method in the home interface * "ItemHome.java". * The parameter sets of the two methods are identical. When the client calls * <code>ItemHome.create()</code>, the container (which in WebLogic EJB is * also the home) allocates an instance of this EJBean and * calls <code>ItemHome.ejbCreate()</code>. * <p> * For container-managed persistence, <code>ejbCreate()</code> returns * a null, unlike the case of bean-managed * persistence, where it returns a primary key. * * @param itemId int itemId, * @param temperature String temperature * @param taste String taste * @param ingredients String ingredients * @param servingSize String servingSize * @exception javax.ejb.CreateException * if there is a problem creating the bean */ public ItemPK ejbCreate(int itemId, String temperature, String description, String taste, String ingredients, String servingSize) throws CreateException { System.out.println("Inside ejb Create"+System.currentTimeMillis()); setItemId(itemId); setItemTemperature(temperature); setItemDesc(description); setItemTaste(taste); setItemIngredients(ingredients); setItemServingSize(servingSize); Connection conn = null; PreparedStatement prepStmt = null; ItemPK key = null; try{ conn = getConnection(); prepStmt = conn.prepareStatement("Insert into Item (item_id, item_temperature, item_desc, item_taste, item_ingredients, item_serving_size)Values (?,?,?,?,?,?)"); prepStmt.setInt(1,itemId); prepStmt.setString(2,itemTemperature); prepStmt.setString(3,itemDesc); prepStmt.setString(3,itemTaste); prepStmt.setString(4,itemIngredients); prepStmt.setString(5,itemServingSize); key = new ItemPK(itemId); System.out.println("end of ejb create"+System.currentTimeMillis()); } catch(Exception e){ System.out.println("Error in ejbCreate"); e.printStackTrace(); } finally{ if(conn!=null){ try{ conn.close(); System.out.println( "Connection closed in ejb create"+System.currentTimeMillis()); } catch(Exception e){ System.out.println( "Error while closing connection in ejbCreate"); } } } return key; } /** * This method is required by the EJB Specification, * but is not used by this example. * * @param itemId int itemId, * @param temperature String temperature * @param taste String taste * @param ingredients String ingredients */ public void ejbPostCreate(int itemId, String temperature, String description, String taste, String ingredients, String servingSize) { System.out.println("ItemBean.ejbPostCreate (" + itemId + ")"+System.currentTimeMillis()); } /** * Accessor mutator methods for each of the variables of the bean. */ public int getItemId(){ return this.itemId; } public void setItemId(int itemId){ this.itemId = itemId; } public String getItemDesc(){ return this.itemDesc; } public void setItemDesc(String itemDescription){ this.itemDesc = itemDescription; } public String getItemIngredients(){ return this.itemIngredients; } public void setItemIngredients(String itemIngredients){ this.itemIngredients = itemIngredients; } public String getItemTemperature(){ return this.itemTemperature; } public void setItemTemperature(String itemTemperature){ this.itemTemperature = itemTemperature; } public String getItemTaste(){ return this.itemTaste; } public void setItemTaste(String itemTaste){ this.itemTaste = itemTaste; } public String getItemServingSize(){ return this.itemServingSize; } public void setItemServingSize(String itemServingSize){ this.itemServingSize = itemServingSize; } /** * finder methods: * find by primary key and findIngredientsByItemName(String itemName) */ public ItemPK ejbFindByPrimaryKey(ItemPK primaryKey) throws FinderException, RemoteException{ System.out.println( "ItemBean.ejbFindByPrimaryKey"+System.currentTimeMillis()); Connection conn = null; PreparedStatement prepStmt = null; try{ conn = getConnection(); prepStmt = conn.prepareStatement( "Select item_id FROM item where item_id=?"); itemId = primaryKey.itemId; prepStmt.setInt(1, itemId); ResultSet rs = prepStmt.executeQuery(); while(rs.next()){ itemId = rs.getInt("item_id"); } System.out.println( "end of find by primary key"+System.currentTimeMillis()); } catch(Exception e){ System.out.println("Error occurred in ejbFindByPrimaryKey"); e.printStackTrace(); throw new EJBException( "SQL update failed. ejbFindByPrimaryKey( ) failed"); } finally{ try{ if(conn != null){ conn.close(); System.out.println( "closed connection of ejb find by primary key"+ System.currentTimeMillis()); } } catch(Exception e){ e.printStackTrace(); } } return primaryKey; } /** * Gets current connection to the connection pool. * * @return Connection * @exception javax.ejb.EJBException * if there is a communications or systems failure */ private Connection getConnection() throws SQLException { InitialContext initCtx = null; try { initCtx = new InitialContext(); DataSource ds = (javax.sql.DataSource) initCtx.lookup("jndi-name-bmp-datasource"); System.out.println("in get connection"); return ds.getConnection(); } catch(NamingException ne) { System.out.println( "Failed to lookup JDBC Datasource. Please double check that"); System.out.println( "the JNDI name defined in the resource-description of the "); System.out.println( "EJB's weblogic-ejb-jar.xml file is the same as the JNDI name "); System.out.println( "for the Datasource defined in your config.xml."); throw new EJBException(ne); } finally { try { if(initCtx != null) initCtx.close(); System.out.println("closing connection in get connection"); } catch(NamingException ne) { System.out.println("Error closing context: " + ne); throw new EJBException(ne); } } } }

The important methods of this class that you need to focus on are ejbCreate(), ejbRemove(), ejbLoad(), ejbStore(), ejbFindByPrimaryKey(), and getConnection().

The ejbCreate() method is invoked by the EJB container when the ItemBean entity bean is created. The ejbCreate() method takes different parameters, such as itemId, temperature, description, and so on. The method starts by obtaining a JDBC connection and then building the insert SQL statement using a PreparedStatement. The getConnection() method looks up the jndi-name-bmp-datasource datasource in the JNDI naming context and executes its getConnection() method. This is the JDBC connection that will be used by other methods of the entity bean to obtain a JDBC connection. The parameters passed to the ejbCreate() method will in turn be used to set values for the insert statement using the setXXX() methods of the PreparedStatement. Because you do not wish to insert any data in the database at this time, you will not invoke the execute() method of the PreparedStatement.

The entity bean uses the ejbLoad() method to synchronize its state with the database. In this case, you will write a select SQL statement in this method. The parameter for this select SQL statement is the itemId of the bean's current instance, which is obtained from the ItemPK primary key class using the getPrimaryKey() method of the ItemBean's EntityContext. After executing the select SQL statement, you need to traverse the result set and extract the retrieved data, such as itemDesc, itemTaste, and so on. This retrieved data is then set in the current instance of the entity bean.

Similarly, to synchronize the database with the current state of the entity bean, you will write an update SQL statement in the ejbStore() method. The update SQL statement uses a PreparedStatement and sets the values of the instance variables that need to be persisted in the PreparedStatement. After the executeUpdate() method of the PreparedStatement is invoked, the current data in the ItemBean entity bean is persisted to the database.

The ejbFindByPrimaryKey() method contains a select SQL statement that retrieves a primary key from the database for a specific itemId. This itemId is the member variable of the ItemPK primary key class of the ItemBean entity bean. Executing the select SQL statement returns a result set from which you can extract the retrieved data using the setXXX() methods.

Finally, the ejbRemove() method contains the delete SQL statement, which will delete the entity bean data from the database. The delete SQL statement takes the itemId of the current instance of the ItemBean entity bean and deletes the data from the database.

Contrast this lengthy source code with the code for the ItemBean that uses CMP! Without a doubt, CMP appears to be much simpler to use and cuts down development time.

Compile the Program

Compile the ItemBean entity bean as you did in the previous chapter. An entity bean that uses BMP is compiled in the same way as an entity bean that uses CMP.

After compiling the source Java files of the sample program, you need to define deployment information for the ItemBean entity bean in the ejb-jar.xml and weblogic-ejb-jar.xml files. You need to do this because the EJB container of WebLogic Server requires additional information to determine how to manage an entity bean.

In the ejb-jar.xml deployment descriptor file, you need to register the entity bean using the <entity></entity> tags. The important parameter that you need to list inside these tags is <persistence-type></persistence-type>, and you should give it the value Bean. This indicates to the EJB container that the entity bean is going to be responsible for its persistence. In addition to the type of persistence, you need to specify the Datasource that the entity bean will use for BMP. This information is specified using the <res-ref-name></res-ref-name> tags. Here, you are using the name jdbc/bmpconnectionPool. The <res-type></res-type> tags show that the resource used for the database connection is a javax.sql.DataSource. A snippet of the information that will be added to the ejb-jar.xml deployment descriptor file is given here:

<enterprise-beans> ... <entity> <ejb-name>BeanManagedEntityBean</ejb-name> <home>com.sams.learnweblogic7.ejb.bmp.ItemHome</home> <remote>com.sams.learnweblogic7.ejb.bmp.ItemInterface</remote> <ejb-class>com.sams.learnweblogic7.ejb.bmp.ItemBean</ejb-class> <persistence-type>Bean</persistence-type> <prim-key-class>com.sams.learnweblogic7.ejb.bmp.ItemPK</prim-key-class> <reentrant>False</reentrant> <resource-ref> <res-ref-name>jdbc/bmpconnectionPool</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </entity> </enterprise-beans>

Similarly, you have to register the entity bean in the WebLogic Server specific deployment descriptor file as well as inside the <weblogic-enterprise-bean></weblogic-enterprise-bean> tags. The JNDI name of the entity bean should also be registered here. In addition to this, you should register the JNDI name of the database source that the entity bean will be using to connect to the database. A snippet of the information that will be added to the weblogic-ejb-jar.xml deployment descriptor file is given here:

<weblogic-enterprise-bean> <ejb-name>BeanManagedEntityBean</ejb-name> <reference-descriptor> <resource-description> <res-ref-name>jdbc/bmpconnectionPool</res-ref-name> <jndi-name>jndi-name-bmp-datasource</jndi-name> </resource-description> </reference-descriptor> <jndi-name>BMP_ItemHome</jndi-name> </weblogic-enterprise-bean>

Deploy the Program

The steps for deploying the ItemBean entity bean that uses BMP are exactly the same as the steps that you performed yesterday. Hence, they will not be repeated here.

Execute the Program

After deploying the ItemBean entity bean, start WebLogic Server and then start the Customer EJB client at another command prompt.

As the WaiterBean interacts with the ChefBean stateless session bean, which in turn interacts with the ItemBean, the output shown in Figure 13.1 is displayed on the console of the WebLogic Server.

Figure 13.1. The output of the ItemBean in the command-prompt window of the WebLogic Server console.

With this, you have completed your study of BMP. Now, you will learn about a new concept that provides an alternative to bean-managed persistence: JDO.

Категории