Chapter 6.
CREANG 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 FindbyOfStock ()"
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 GetOfstockItems () Add Another Business Method to StoreAccess Bean with the Signature: Publ ic 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 bellow.
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 Add All these Fields, Press Finish.
This Will Create a package named au.com.tusc.cmp under src, AND ITEMBEAN WILL 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 does not 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 of doe ,,, 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 Chapter Chapter (Chapter) in detail, so please refer to these if you have any queries.
Now, Let's See What Files Have Beenrated 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 Chapter.
@ 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: - THEERE IS An Error In The Figure 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 (eg it has to of type String, Integer, Float, or whatever) In this case it is String. - The Type of itemid, and when implemented it soould 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 .
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 support" "
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.
.............. ..
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
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 FindbyOfStock ()"
Code Snippet from itemlocalhome instance, ejb classes for these Finder Methods.
Now, Generate Your EJB CLASSES AND z The Relevant Classes. All The Finder Methods Are Complete. Let's add some business method.
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)
...........................................
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 SentityContext with EntityContext As its parameter and assign That to your entryxtext 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 Implement 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 descriptor is generated.
Note: We don't have to write one 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
Descriptors for Finder Methods Are Generated Along with The Query Defined to Fetch The Data As Shown Below. Thase Finder Tags Are Generated by The @ Ejb.finder Tag Declared At Class Level.
And in the jboss.xml file, The following descriptors area generated due to the tag @ Ejb.bean declared at class level, as shown bellow.
NOTE: @ Ejb.bean tag Has been covered in previous chapter.
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 Chapter Chapter (1 and 3), So, please refer to them.
.................. ..
Now, Lets Modify StoreAccessBean to Invoke Methods on Itembean.
Add a field to store our item reason (Obtained from JNDI Lookup).
Private itemlocalhome itemlocalhome;
In The Ejbcreate Method Store This Reference In The Itemlocalhome Variable by Invoking The GetLocalhome Static Method in This Code Snippet Below from Store Access Bean.
Add a Business Method to StoreAccess:
Add Another Business Method to The StoreAccess Bean Which Will Invoke This Business Method on Our Item Bean.
Now, Add A Business Method with this signature:
Public ItemData GetItemData (String ItemID)
.. with Interface type as Remote. As managers will log on to MyStore with username, once authenticated they will be identified by their userid. They can then retrieve their account details from MyStore using that userid. A Manager can invoke methods on the Item Bean TO Examine the inventory of mystore.
NOTE: Steps to create Business Methods Are Covered in Previous Chapter.
NOW INVOKE ONE OF ITEM'S Finder Methods Via The Reference Variable We Have Created In The Ejbcreate Method.
Itemlocal item = itemlocalhome.findbyprimaryKey (itemid)
Now Invoke The Business Method of Customer on this reference.
ItemData myitem = item.getitemdata ()
.
Add a Business Method with this signature:
Public Java.util.Arraylist GetOfStockItems ()
.. with interface Type As Remote. This Will Return The Items Which Are Out of stock in MyStore.
Create two variables of type Collection and ArrayList respectively, as the finder method for Items returns a Collection and this method will return an ArrayList, after populating items which are out of stock from the returned Collection.
Collection items = NULL;
ArrayListItemSoutofstock = NULL;
Now Invoke One of the Finder Methods of Item on The Reference Variable We Have Created in The Ejbcreate Method.
items = itemlocalhome.findbyOutofstock ()
Now Iteerate Through The Collection of Out of stock items and add to the arraylist.
Itemlocal myitemlocal = (itemlocal) Iterate.next ();
ItemsOutofstock.add (myitemlocal.getitemdata ());
Code Snippet for this Business Method is shown BELOW.
Add Another Business Method to StoreAccess Bean.
Add a Business Method with this signature:
Public Java.util.ArrayList GetItemBysupplier (String SupplierID)
. This will return the item. this will return...............
Create two variables of type Collection and ArrayList respectively as the finder method for Items returns a Collection and this method will return ArrayList, after populating items which are supplied by a particular supplier from the returned Collection.
Collection supportItems = NULL;
ArrayList itemsBysupplier = NULL;
Now Invoke One of the Finder Methods of Item on The Reference Variable We Have Created in The Ejbcreate Method.
SuppliedItems = itemlocalhome.findbysupplierid (support) No Ite The Collection of iTeem for this support of add to the arraylist.
Itemlocal myitemslocal = (itemlocal) Iterate.next ();
ItemsBysupplier.Add (myitemslocal.getitemdata ());
Code Snippet for this Business Method is shown BELOW.
Now all the methods in StoreAccess Bean for accessing Item's business methods have been added. The only remaining bit is the deployment descriptors required for linking / referencing of StoreAccess and Item Bean. So we will the add two tags shown below.
First Add The Tag Shown Below At Class Level in StoreAccess Bean.
@ Ejb.ejb-ref ejb-name = "item"
View-type = "local"
REF-Name = "itemlocal"
This tag will generate deployment descriptors in 'ejb-jar.xml', as StoreAccessBean has to know which bean it is referring to, what is its view-type and ref-name. This will generate these descriptors as shown below.
Note: View type is local as both are in the same Java Virtual Machine, otherwise it would be Remote Secondly ref-name is generated as ItemLocalHome, as we are using that rather than ItemHome (which was also generated, but is used in the. REMOTE case.
NOW Add A Second Tag (Shown Below) At Class Level In StoreAccess Bean.
@ jboss.ejb-ref-jndi ref-name = "itemlocal"
JNDI-NAME = "itemlocal"
THIS TAG WILL Generate Deployment Descriptors in 'jboss.xml', As the Application Server Has To Know What Jndi-Name The Item Bean Has Been Registered with. This Will Generate The Descriptors As Shown Below.
NOTE: REF-NAME AND JNDI-NAME ARE Used for Bean As Local (In Same JVM).
Note: We can see in the code snippet above the deployment descriptors generated by tag @jboss For the view type 'local' it generates incorrect deployment descriptors, as discussed in the previous chapter So every time we use this tag we have to change.. the
Once the bean is deployed successfully, create a test client which will invoke the loginUser method on StoreAccess Bean, getCustomerData on Customer Bean, getManagerData on Manager Bean and getOutOfStockItems on Item Beam.
Create Your Test Client:
Go to Project MyTORE NODE> SELECT SRC Node and Expand It> Select au.com.tusc.client package> Right Click.
Select New On The Pop Up Menu> SELECT LOMBOZ EJB Test Client Wizard.
Select package name au.com.tusc.client, name as sessioncmpclient and select ejb home as au.com.tusc.session.storeAccessHome and ejb interface as au.com.tusc.session.storeAccess.
This will generate required methods for you in your SessionCMPClient class and you only have to invoke loginUser, getCustomerData, getManagerData (Manager Bean was developed as part of an exercise in the previous chapter) and getOutOfStockItems as shown below.
Now, The Last Step is to write the code for your client.
In order to access out of stock items we need an Iterator and an ArrayList for items. So, declare two variables of these respective types, and import the packages for these types (which are java.util.ArrayList and java.util.Iterator) .Iterator itemsiterator = null;
ArrayList items = NULL;
And now THESE LINES OF CODE INVOKE The Methods Mentioned Above.
System.out.println ("Request from Cliant:");
String userid = mybean.loginuser ("andy", "passwd");
System.out.println ("Reply from Server: Your Userid IS" UserID;
CustomerData CD = MyBean.getCustomerData (userID);
System.out.println ("Andy Your Details with MyStore Are" CD);
String mgrid = MyBean.loginuser ("Rusty", "Passwd");
System.out.println ("Reply from Server: Your Mgrid IS" MGRID);
ManagerData MD = MyBean.getManagerData (MGRID);
System.out.println ("Rusty Your Details with MyStore Are" MD);
System.out.println ("Manager Request: List items out of stock";
Items = myBean.getOutofstockItems ();
Itemsiterator = items.iterator ();
System.out.println ("List of out of stock items");
While (itemsiterator.hasnext ()) {
Itemdata itemdata = (itemdata) itemsiterator.next ();
System.out.println ("item data" itemdata;
}
Test Your Client:
Now, in Order to Test Your Client, Select Sessioncmpclient Node> Go At Top Level Menu and SELECT The icon with the 'Running Man'.
On That Select 'Run As'> Select Java Application, AS Shown Below.
Now on your console, if you get a reply Saying Two items out of stock which area 'Calculator' and 'clock', The Your Call Is Successful As Shown Below.exercise:
Now, Here Is An Exercise for you. In Order To Proceed Further, Implement Supplier AS A CMP Entity Bean. The Tasks Area Given Below:
Create a CMP Bean named Supplier under package au.com.tusc.cmp Implement the ejbCreate method, with all attributes passed as arguments and then assigned to attributes using mutator methods Add a find method named findUserID with query and signature:.. Query "SELECT OBJECT (b) FROM MyStoreSupplier as b where b.userID = 1 "method au.com.tusc.cmp.SupplierLocal findUserID (java.lang.String userID) Note:? The method signature is find
Add a business method to StoreAccess Bean with signature: public ItemData getItemData (String itemID) Add the following tags for deployment at class level for linking / referencing Supplier.1 @ ejb.ejb-ref ejb-name = "Supplier".
View-type = "local"
Ref-name = "SupplierLocal"
2. @ jboss.ejb-ref-jndi ref-name = "supportlorelocal"
JNDI-NAME = "SupplierLocal"
Test Your Supplier Bean by Running Your Test Client Created for Item Named SessioncmpClient.
NOTE: All these Steps Are Same Asne Done for Item. Implement this bean which will be used in subsequent chapter.
In Case You Have Difficulty, We Have PROVIDED A SUPPLIERBEAN CLASS, Modified StoreAccessBean Class and SESiomcmpclient Class. You Can Download Sests Under Downloads Below.
Downloads:
Supplierbean
StoreAccessBean
SessioncmpClient