Tutorial for building J2EE Applications using JBOSS and ECLIPSE (6)

类别:Java 点击:0 评论:0 推荐:
Chapter 6.

Creating a CMP Entity Bean

This chapter covers how to create a Container Managed Persistence (CMP) EJB component. We will create two CMP beans, Item and Supplier as shown below. The Item bean will be responsible for storing the details of items, such as their availabability and their prices, for MyStore. The Supplier Bean stores details of Suppliers to MyStore. Both beans interact with corresponding tables in the database. In CMP this interaction is controlled by the container, in this case the JBOSS CMP container.





All Items have been assigned a unique itemId for housekeeping purposes within MyStore, and all suppliers have been assigned a unique supplierID in addition to their username which is what they use in accessing the services of MyStore.



Note : It is normal practice to access the business methods of CMP beans via a Session bean, that encapsulates the business logic and acts as an interface to the lower-level EJB components. In this case Supplier and Items are accessed via StoreAccess.

Tasks :

Create a CMP bean named Items under package au.com.tusc.cmp.

Implement the ejbCreate method, with the values of all attributes being passed as arguments and then assigned to the attributes using mutator (setter) methods.

Add a finder method named findBySupplierID with the following query and signature:

query "SELECT OBJECT(b) FROM MyStoreItem as b where b.supplierID = ?1"

method "java.util.Collection findBySupplierID(java.lang.String supplierID)"

Add a finder method named findByOutOfStock with the following query and signature:

query "SELECT OBJECT(c) FROM MyStoreItem as c where c.quantity = 0"

method "java.util.Collection findByOutOfStock()"

Add a business method to get item details with the signature:

public ItemData getItemData()

Add another business method to register delivery of items with the signature:

public void fillStock(java.lang.Integer quantity)

Add callback methods, required for getting/setting bean context for bean with signatures:

public void setEntityContext(EntityContext ctx)

public void unsetEntityContext()

Deploy the Item Bean.

Add a field to the StoreAccess bean to store the Item reference (obtained from JNDI lookup):

private ItemLocalHome itemLocalHome

In the ejbCreate method of the StoreAccess bean store this reference in the itemLocalHome variable by invoking the getLocalHome static method in ItemUtil.

Add a business method to StoreAccess Bean with the signature:

public ItemData getItemData(String itemID)

Add another business method to StoreAccess Bean with the signature:

public java.util.ArrayList getOutOfStockItems()

Add another business method to StoreAccess Bean with the signature:

public java.util.ArrayList getItemBySupplier(String supplierID)

Create a test client named SessionCMPClient under package au.com.tusc.client.

Run your client and test the bean.


Create Items CMP 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 the package name au.com.tusc.cmp, the bean name Item and select the bean type as Container Manged Entity as shown below.



Go to Next and a new screen will pop up as shown below.

Enter MyStoreItem as the Schema Name.

Enter Item as the Table name.

Under Persistent Fields first enter itemID as the Field, with a Field Type of java.lang.String, ITEMID as its Database column, and VARCHAR for its SQL Type.

Press Add .. > It will add this field in Fields section, select this new field > Press Make Primary Key.


Similarly, add all the rest of the fields of the items table as shown below.

Add .. Field: supplierID, Field Type: java.lang.String, Database Column: SUPPLIERID, SQL Type: VARCHAR.

Add .. Field: description, Field Type: java.lang.String, Database Column: DESCRIPTION, SQL Type: VARCHAR.

Add .. Field: quantity, Field Type: java.lang.Integer, Database Column: QUANTITY, SQL Type: INTEGER.

Add .. Field: price, Field Type: java.lang.Float, Database Column: PRICE, SQL Type: DECIMAL.




After adding all these fields, press Finish.

This will create a package named au.com.tusc.cmp under src, and ItemBean will be be created within that package as shown below.

Note: In comparison with our earlier BMP Entity Beans (Customer & Manager), more tags have been generated at class level. Note also that CMP doesn't require a Data Access Object (DAO) interface, as communication between database and bean is controlled by the container.

Let's first the generate EJB classes and then we will examine these tags.

Go to node ItemBean under au.com.tusc.cmp > 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 (chapters 3 and 1) in detail, so please refer to these if you have any queries.

Now, let's see what files have been generated by Xdoclet.

As shown below, the files generated are nearly the same as for BMP, except there are no Primary Key or DAO classes, and there is now ItemCMP which extends the ItemBean class. The remainder are the same as for BMP entity beans.

Now, let's examine these new tags, some of which have been covered in previous chapters.

@ejb.bean tag provides information about the EJB. It is the one compulsory tag for all EJBs.

@ejb.persistence tag is being used at two levels, at class level and method level. At class level it provides information about the persistence of a CMP entity bean, that is which database table this bean is going to interact with, which will provide that persistence. At method level it provides information about the mapping of the bean's persistent attributes to columns in that database table.

@ejb.finder tag defines a finder method for the home interface. This requires the EJB QL query to fetch the data and a signature for the method. This tag can be used for multiple finder methods.

@ejb.persistence-field method level tag is being deprecated in favour of @ejb.persistence tag, it provided information about persistent fields.

@ejb.pk-field tag defines the primary key.

The code snippet below shows how persistent attributes are declared in a CMP Entity Bean.


Note: All persistent attributes are declared with abstract accessor and mutator methods in ItemBean. Note also that in the case of a composite primary key you have to specify the @ejb.pk-field tag on all other attributes/properties which combine to form the overall key as well.


Implement ejbCreate Method :

The ejbCreate method is created by method is created by the Lomboz Bean wizard, but we still have to add some code to complete it. Modify the signature of ejbCreate, passing all the attributes as parameters and then setting all these attributes using their associated mutator methods, as shown below.

Errata note :- There is an error in the figure shown below. The Integer attribute 'qunatity' should be called 'quantity'.

Note : The other interesting aspect of ejbCreate here is its return type, as its return type has to be same as the primary key type (e.g. it has to of type String, Integer, Float, or whatever). In this case it is String - the type of itemID, and when implemented it should return null.(Refer to the EJB Spec 10.5.1).


Add Finder Method :


Note: An entity bean's home interface defines one or more finder methods, to find an entity object or collection of entity objects. The name of each finder method starts with the prefix 'find', such as findPrice or findQuantity in our case. Every finder method except findByPrimaryKey(key) must be associated with a query element in the deployment descriptor. The entity bean provider declares the EJB QL finder query and associates it with the finder method in the deployment descriptor. A finder method is normally characterized by an EJB QL query string specified via the query element. Refer to the EJB Spec 10.5.6. This is covered in the Exercise section of this chapter.

Now let's add a finder method to our bean class to find items supplied by a particular supplier.

In order to add this finder method we have to declare a class level tag as discussed above, that is @ejb.finder.

So, add this tag:

@ejb.finder query="SELECT OBJECT(a) FROM MyStoreItem a where a.supplierID = ?1" signature="java.util.Collection findBySupplierID(java.lang.String supplierID)"

Note : In EJB QL, instead of the name of the table, the schema name is used (in this case it is MyStoreItem, rather then specifying Item as you would for an SQL query). Similarly the column names that would be used in SQL are replaced by their corresponding attributes as declared in the bean.

Generate your EJB classes to see what this tag and the previous finder tag have created in the Home Interface as shown below in this code snippet from the ItemLocalHome interface.

It has four methods, including the two finder methods generated by the finder tags declared at class level. The other two, create and findByPrimaryKey are created by Xdoclet(because of the <entitycmp/> tag in ejbGenerate.xml).


Add another finder method to find out-of-stock items in MyStore.

Add the following tag.

@ejb.finder query="SELECT OBJECT(c) FROM MyStoreItem c where c.quantity = 0" signature="java.util.Collection findByOutOfStock()"

Code snippet from ItemLocalHome after generating EJB classes for these finder methods.


Now, generate your EJB classes and analyze the relevant classes. All the finder methods are complete. Let's add some business methods now.

Add Business Methods :

Now, add a business method with this signature:

public ItemData getItemData()

.. 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 as local because these methods will be invoked within the same Java Virtual Machine.

This will provide description of individual items in MyStore. Add some debug statements and return an instance of ItemData as shown below in this code snippet from the Item bean.



Add another business method with the following signature:

public void fillStock (Integer quantity)

.. with Interface type as local. This will increment the items available to MyStore after the delivery of further items. Add some debug statements and following lines to complete the method.

Integer qty = new Integer( (quantity.intValue() + getQuantity().intValue()) ) ; setQuantity ( qty );

Code snippet of fillStock in ItemBean shown below.



Add Callback Method

Unlike BMP (where they were generated) we have to add callback methods which will be overridden in the ItemCMP class.

First import the following package: javax.ejb.EntityContext

Add a field to store the entity context.

protected EntityContext eContext;

Add a method setEntityContext with entityContext as its parameter and assign that to your entityContext variable.

Similarly add a method unsetEntityContext, which sets the entityContext variable to null.

Code snippet for both methods is shown below.

Now all business and finder methods are complete, so it's time to generate EJB classes.

Let's examine the generated ItemCMP class, which is of most interest .

Unlike our BMP bean all persistent attribute behavior is being overridden by abstract methods. This is because the EJB container is responsible for maintaining their persistence.



All the callback methods we have implemented are being overridden as shown below.

Note : There are no ejbFinder methods in this class as with BMP beans, as all this is controlled by the container. Also as pointed out before, there is no PrimaryKey class generated and there is no need for a DAO class, as this too is controlled by the container.

Now, before we deploy our bean, we will just have a look at ejb-jar.xml and jboss.xml to see what descriptors are generated.

Note : We don't have to write any descriptors for the data sources as we did with Session and BMP beans, as the EJB container is responsible for that.

As shown in the code snippet above from the ejb-jar.xml file, all abstract methods are generated as persistent fields under the tag <cmp-field> because of the tag @persistence-field declared at each accessor method. Also the primary key class descriptor is generated under the <primary-key-class> tag and the primary key field is generated under the <primarykey-field> because of the tag @field-pk declared for the relevant attribute(s).

Descriptors for finder methods are generated along with the query defined to fetch the data as shown below. These finder tags are generated by the @ejb.finder tag declared at class level.

And in the jboss.xml file, the following descriptors are generated due to the tag @ejb.bean declared at class level, as shown below.

Note : @ejb.bean tag has been covered in previous chapters.

Item Bean functionality is complete in and ready for deployment.

Deploy Item Bean :

Go to Lomboz J2EE View > expand node MyStore > expand MyStoreMgr > select Jboss 3.2.1 ALL.

Right click > select Debug Sever on the pop up menu.

Note : This is to start your server, if you are already running your server then skip these steps and go to the next one.

Go to MyStoreMgr node in LombozJ2EE view > right click > select Deploy on the pop up menu as shown below.



Note : All these steps have been detailed in previous chapters (1 and 3), so, please refer to them.

Messages in the console will indicate whether deployment of your bean has been successful or not.

Now, lets modify StoreAccessBean to invoke methods on ItemBean.

Add a field to store our Item reference (obtained from JNDI lookup).

private

本文地址:http://com.8s8s.com/it/it9683.htm