您可以在这里快速查找:


 
您的位置: 编程学习 > java教程 > 200507
文章分类

Java技术
2005: 03 04 05 06 07 08
09 10 11 12
2006: 01 02

Asp.net
2005: 07 08 09 10 11 12
2006: 01 02

VB编程
2006: 02

Asp编程
2005: 11 12
2006: 01 02

C++/VC
2005: 10 11 12
2006: 01 02

Delphi
2005: 12
2006: 01 02

其它

 本文章适合所有读者

Tutorial for building J2EE Applications using JBOSS and ECLIPSE -5

jhlcss

Chapter 5.

Creating a BMP Entity Bean

This chapter describes how to create a Bean Managed Persistence (BMP) EJB component. We will create two BMP beans, Customer and Manager, as shown below. The Customer bean will be responsible for storing the details of customers of MyStore. The Manager bean stores details of the manager of MyStore. Both beans communicate with their respective tables in the database using Data Access Objects (DAOs) named CustomerDAO and ManagerDAO respectively.






All customers have been assigned a unique customerID for housekeeping purposes in MyStore in addition to their username for accessing the services of MyStore. Similarly the Manager of MyStore has been assigned a unique ManagerID.



Note : It is the usual practice to access business methods of BMP beans via a session bean, which encapsulates business logic and acts as an interface to further EJB components. In this case Customer and Manager are accessible via by StoreAccess.

This approach comes from a pattern called a Session Facade, whereby enterprise beans encapsulate business logic and business data and expose their interfaces. The session bean acts as a facade to encapsulate the complexity of interactions with the lower-level beans. The session facade is responsible for managing business objects and provides a uniform business service abstraction to presentation layer clients, thereby hiding the business object implementation in the lower-level beans.

This tutorial uses that pattern for business tier implementation.

Tasks :

  1. Create a BMP bean named Customer under package au.com.tusc.bmp.

  2. Create a DAO class named CustomerDAOImpl under package au.com.tusc.dao.

  3. Add all attributes/properties to the CustomerBean, with getter and setter methods for each of the attributes.

  4. Add a finder method named ejbFindByPrimaryKey with the signature

    public CustomerPK ejbFindByPrimaryKey (CustomerPK pk) throws FinderException

  5. Add a finder method named ejbFindByUserID with the signature

    public CustomerPK ejbFindByUserID (String userID) throws FinderException

  6. Add a business method named getCustomerData with the signature

    public CustomerData getCustomerData()

  7. Implement required methods in the CustomerDAOImpl class.

  8. Deploy the Customer Bean.

  9. Add a create method to the StoreAccess Bean.

    public void ejbCreate() throws javax.ejb.CreateException

  10. Add a business method to the StoreAccess Bean.

    public CustomerData getCustomerData(String userID)

  11. Create a test client named SessionBMPClient under package au.com.tusc.client.

  12. Run your client and test the bean.


Create the Customer BMP Entity Bean :


Go To Package Explorer > Expand Mystore (project) node > select src, right click and a menu will pop up.

On the pop up menu > New > Lomboz EJB Creation Wizard.

Enter package name au.com.tusc.bmp, bean name Customer and select bean type as Bean Manged Entity > Finish.

This will create a package named au.com.tusc.bmp under src and CustomerBean under that package as shown below.


Note: It will generate the bean name, jndi-name and type of bean in file. Also, the word ´Bean´ is appended to the name of the file.

As we can see from the figure above it has created a class level tag @ejb.bean, which has assigned the bean type, its name and its JNDI name which will be generated in the Home interface. This tag will also generate deployment descriptors in ejb-jar.xml and jboss.xml file once you generate your EJB classes.

Now we are going to generate all the interfaces including Home, Remote, DAO and other helper classes. We don´t need to specify any tags in ejbGenerate.xml as we have already set up that for the MyStoreMgr EJB module in chapter 3.

Go to node CustomerBean under au.com.tusc.bmp > LombozJ2EE > Add EJB to Module > Select MyStoreMgr > Ok.

Go to MyStoreMgr node > LombozJ2EE > Generate EJB classes.

Note: All these steps are covered in previous chapters (chapter 3 and 1) so please refer to those sections if you need further details.

Now let´s see what files are generated by Xdoclet.

As shown below there are two new files named CustomerData and CustomerPK in addition to what we had for our session beans. We also have a CustomerBMP which extends our CustomerBean class. The remaining files should be familiar from our work with session beans.


As discussed in chapter 3 regading the various ejbDoclet tags used in ejbGenerate.xml, to generate these classes, CustomerData and CutomerPk are generated by following tags as shown below in this snippet from ejbGenerate.xml:

The relevant tags are <dataobject/> and <entitypk/>.


Note: There is no CustomerDAO class, as we haven´t generated that file by specifying the dao tag in the CustomerBean class.

Create Customer´s DAO Interface :


Since we are going to use a DAO to access database for this bean, we have to create a DAOImpl class to provide an implementation for the generated DAO interface.

Go to src > package au.com.tusc.dao > Add a class CustomerDAOImpl in that package.




Now go to your bean class and declare this tag at class level (ie. at the top) as shown below to generate the DAO interface.

@ejb.dao class="au.com.tusc.bmp.CustomerDAO" impl-class="au.com.tusc.dao.CustomerDAOImpl"





Regenerate your classes and check that your DAO interface is generated.

Note : For reference the steps are as follows:

Expand MyStoreMgr node under MyStore Project in Package Explorer.

Right click and a pop up menu will appear.

Go to Lomboz J2EE > Generate EJB Classes as shown on the right.

As shown below, our DAO interface is generated.










If we look at the generated DAO class as shown below, it has four more methods than StoreAccess (which was a Stateless Session Bean) did when we first generated it (ie. prior to adding the method level @dao:call tag).

Note : It´s worth mentioning here that BMP Entity beans don´t need the @dao:call tag for generating DAO interface methods.




All these methods are generated by the tag described earlier for DAO interface generation, also shown below.



Also, let´s look at the descriptors generated up until this step, in ejb-jar.xml under MyStoreMgr/META-INF.

These descriptors are generated by the following tag in CustomerBean.

@ejb.bean name="Customer" jndi-name="CustomerBean" type="BMP"


This tag generates descriptors in jboss.xml as well, which will be covered later on.





The next step is to add attributes/properties to our Customer Bean, which will be accessible to clients through the remote interface using getter and setter methods. These attributes are mapped to corresponding columns in the relevant table in the database.


In order to add these properties/attributes , define all attributes (as private to encapsulate) and their corresponding accessors/mutators (getter and setter methods). Each accessor (getter) method will have two tags or three in the case of a primary key. The mutator (setter) method will have only one tag declared on it.

Add these tags for attributes/properties (in Bean terms) as shown below.

/**

* Returns the customerID * @return the customerID * * @ejb.persistence * @ejb.pk-field * @ejb.interface-method */ public java.lang.String getCustomerID() { return customerID ; } /** * Sets the customerID * @param java.lang.String the new customerID value * * @ejb.interface-method */ public void setCustomerID (java.lang.String customerID) this.customerID = customerID;

}

Code snippet from CustomerBean is shown in figure at right.



Now, analyzing these tags,

  1. @ejb.persistence specifies this as a persistent attribute. All accessor and mutator methods will be overridden in generated BMP class, in this case it is CustomerBMP, and all mutator methods will have a dirty flag in them, as persistence is controlled by ejbLoad() and ejbStore().

  2. @ejb.pk-field specifies that this attribute is mapped to a primary key in database and and is assigned as a primary key in the PrimaryKey class, in this case the CustomerPK class.

  3. @ejb.interface generates these methods in the Remote interface.

Now, in the case of mutator methods (that is ´setCustomerID´) the only tag required is @ejb.interface-method for generating this method in the remote interface.

Similarly, add methods and their tags for rest of the persistent fields. There will be no @ejb.pk-field tag as customerID is the primary key.

Note : In the case of a composite primary key you have to specify @ejb.pk-field tags on the other attributes/properties which make up the composite key.

Similarly, Add tags and methods for rest of the persistent fields, which in this case are, firstName, lastName, Address, phone and shareholderStatus as shown in this code snippet from CustomerBean.



Generate EJB classes and examine what methods are generated in the various classes, particularly in CustomerBMP and CustomerData.


Add Finder Methods :


Now let´s add a finder method to our bean class.

Add a method with this signature:

public CustomerPK ejbFindByPrimaryKey (CustomerPK pk) throws FinderException


Put some debug statements in it and return null as shown below.



Now when we generate our EJB classes this method will be overridden in CustomerBMP. Also this method will call a corresponding method from CustomerDAO interface as shown below in this code snippet from CustomerBMP.




This will also create methods in the Home interface and DAO interfaces as shown below.





Add another finder method to CustomerBean, with the signature


public CustomerPK ejbFindByUserID (String userID) throws FinderException


Put some debug statements in it and return null as shown below.


Note : As stated in the EJB spec 12.8.1 all finder methods should return the Primary Key.


Again, regenerate your EJB classes, and there will be methods created in the CustomerHome interface, CustomerBMP and CustomerDAO, similar to those that were created for ejbFindByPrimaryKey.

A code snippet from the CustomerDAO class, after generating the EJB classes.



Add Business Methods :

Now, add a business method with the signature

public CustomerData getCustomerData() with Interface type as local.

Note : The steps to add a business method are covered in previous chapters (1 and 3), so please refer to them. Also, we have chosen the interface type to be local because these methods will be invoked in the same Java Virtual Machine. In this case they will be invoked by the stateless bean StoreAccess.

This will provide the details of an individual customer. Add some debug statements and return an instance of CustomerData as shown below in this code snippet from CustomerBean.



Make sure you generate your EJB classes again before you start implementing Customer´s DAO interface.



Implement Customer´s DAO Interface :

Now let´s implement our methods in CustomerDAOImpl class.

CustomerDOAImp class under package au.com.tusc.dao implements methods generated in CustomerDAO class under package au.com.tusc.bmp.

First import the following packages.

javax.naming.InitialContext; javax.sql.DataSource; java.sql.Connection; java.sql.PreparedStatement; java.sql.ResultSet; java.sql.SQLException;

Change your class declaration so that CustomerDAOImpl implements CustomerDAO.

Add a field to store the JDBC resource factory reference.

private DataSource jdbcFactory;

In the init() method, locate the reference jdbc/DefaultDS using the JNDI API, and store the reference in variable jdbcFactory.

The lookup string is "java:comp/env/jdbc/DefaultDS".

Code snippet is shown below.




In method load(), first get the connection to the database using field jdbcFactory. Create a SQL statement which searches for a record corresponding to customerid in table Customer, where customerid is the primary key. Code snippet is shown below.




In method store(), first get the connection to database using field jdbcFactory. Create an SQL statement which updates a record corresponding to customerid in table Customer, where customerid is the primary key. Code snippet is shown below.




In method ejbFindByUserID(), first get the connection to database using field jdbcFactory. Create an SQL statement which searches for the customerid corresponding to a given userid in table Customer, where customerid is primary key. Code snippet is shown below.




In method ejbfindByPrimaryKeystore(), first get the connection to database using field jdbcFactory. Create an SQL statement which searches for customerid in table Customer, where customerid is the primary key. Return the primary key. Code snippet is shown below.


Also, you should implement methods remove and create. We´re leaving those as an exercise for you (you´ve probably got the idea by now!), or you can leave them as stubs as shown below.




Now our CustomerDAOImpl class is finished. Generate your EJB classes again.

After generating your EJB classes, let´s look at the Home Local Interface and the Remote Local interface.

In the Remote Local Interface (which is CustomerLocal in this case), there is one business method exposed, and the rest are all the methods to access the attributes/properties of the bean (as we also declared these methods as interface methods in CustomerBean), as shown below. These methods are generated by @ejb.interface-method tag.




In the Home Local Interface, which is CustomerLocalHome in this case, there are two finder methods as shown below. It has also generated JNDI_NAME and COMP_NAME (logical name to lookup the component).


These names are generated by the following tag declared in CustomerBean as shown below.




Note : We are not currently interested in the Customer interface (which is a Remote interface) and CustomerHome (which is a Remote Home interface), because we are accessing bean methods in the same Java Virtual Machine, so we need only Local interfaces.

Note : In CustomerBean we haven´t implemented any methods for the setting and unsetting of context, because it is generated by Xdoclet in the CustomerBMP class, as shown below.