Sie sind auf Seite 1von 428

Developing Enterprise JavaBeans with VisualAge for Java

Joaquin Picon, Patrizia Genchi, Maneesh Sahu, Martin Weiss, Alain Dessureault

International Technical Support Organization http://www.redbooks.ibm.com

Draft Document for Review March 22, 1999 4:59 pm

SG24-5429-00

SG24-5429-00

International Technical Support Organization Developing Enterprise JavaBeans with VisualAge for Java May 1999

Draft Document for Review April 14, 1999 3:55 pm

5429edno.fm

Draft Document for Review April 14, 1999 3:55 pm

Take Note!

Before using this information and the product it supports, be sure to read the general information in Appendix E, Special Notices on page 379.

First Edition (May 1999) This edition applies to VisualAge for Java Enterprise Edition 2.0 with the Enterprise JavaBeans update for use with the Windows Operating System and WebSphere Advanced Edition 2.0. Comments may be addressed to: IBM Corporation, International Technical Support Organization Dept. QXXE Building 80-E2 650 Harry Road San Jose, California 95120-6099 When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the information in any way it believes appropriate without incurring any obligation to you.

Copyright International Business Machines Corporation 1999. All rights reserved Note to U.S Government Users Documentation related to restricted rights Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp.

Contents
Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii The Team That Wrote This Redbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii Comments Welcome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xix

Part 1. Enterprise JavaBeans: essentials . . . . . . . . . . . . . . . . . . . . . . .1


Chapter 1. Moving business logic to Enterprise JavaBeans . . . . . 3 1.1 Stand-alone application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 High volume transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.3 San Francisco application frameworks. . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.4 Distributed Object-Oriented Technologies . . . . . . . . . . . . . . . . . . . . . . . . 7 Microsoft DCOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 CORBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Chapter 2. Enterprise JavaBeans: Quick Start . . . . . . . . . . . . . . . . 11 2.1 Roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Deployer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Application Assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Container Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Server Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 System Administrator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.2 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Container. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Session and Entity JavaBeans. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Session Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Entity Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.3 An Overall Picture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Chapter 3. Developing a Session bean . . . . . . . . . . . . . . . . . . . . . . . . 19 3.1 Session Beans Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Basic Components of a Session Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Stateless Versus Stateful Session Beans . . . . . . . . . . . . . . . . . . . . . . . . 20

Copyright IBM Corp. 1999

iii

3.2

3.3

3.4

3.5

3.6 3.7 3.8

Session Bean Life Cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Creation state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Ready state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Pooled state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Removal state . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Developing Session Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Writing the Enterprise Bean Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Implementing the business methods . . . . . . . . . . . . . . . . . . . . . . . . . 25 Implementing the ejbCreate methods . . . . . . . . . . . . . . . . . . . . . . . . 27 Implementing the SessionBean interface . . . . . . . . . . . . . . . . . . . . . 29 Writing the Home Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Writing the Remote Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 Developing Session Bean inside VisualAge for Java . . . . . . . . . . . . . . . 34 Creating EJBs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 First step: adding EJB Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Second step: adding EJB to EJB Groups . . . . . . . . . . . . . . . . . . . . . . 39 Generating Deployed Code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 The deployment descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 The ejb-jar file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Deploying an enterprise Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 Generate the Test Client. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Testing EJBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Setting Name Service and EJB Server Properties . . . . . . . . . . . . . . 68 Starting the Name Service and EJB Servers. . . . . . . . . . . . . . . . . . . 71 Restarting Servers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Running the Generated Test Client . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Writing Your Own Client Application . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Importing required Java packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Instantiating an EJB Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 Stopping the Name Service and EJB Servers . . . . . . . . . . . . . . . . . . . . . 85 Running the client outside VisualAge for Java . . . . . . . . . . . . . . . . . . . 85 Exporting EJB Groups and EJBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Exporting EJBs to EJS or EJB Jar Files . . . . . . . . . . . . . . . . . . . . . . 85 Exporting EJBs to Client Jar files . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 Running the client outside VisualAge for Java . . . . . . . . . . . . . . . . . . . 90 Deployment on WebSphere Advanced Edition 2.0. . . . . . . . . . . . . . . . . 91 Deployment for Other Enterprise JavaBeans Servers . . . . . . . . . . . . . 97 Deployment using WebSphere tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

Chapter 4. Developing a Container-managed persistence bean 107 4.1 Container-Managed Persistence basics . . . . . . . . . . . . . . . . . . . . . . . . 107 4.2 Developing a CMP Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Creating a Container-managed persistence bean. . . . . . . . . . . . . . . . . 109 Projects, packages and reserved package organization . . . . . . . . . . . . 118

iv

Developing Enterprise JavaBeans with VisualAge for Java

Understanding the generated types . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 Adding fields to the Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Removing a field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Regarding the other modifiers (final, transient, static) . . . . . . . . . 129 Working with the key Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 4.3 Understanding the generated methods . . . . . . . . . . . . . . . . . . . . . . . . 132 Life cycles of enterprise Bean instances . . . . . . . . . . . . . . . . . . . . . . . . 132 Creation State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Pooled State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 Ready State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 Removal State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 The CustomerBeans generated methods . . . . . . . . . . . . . . . . . . . . . . . 134 The CustomerHome interfaces generated methods . . . . . . . . . . . . 136 The CustomerKeys generated methods. . . . . . . . . . . . . . . . . . . . . . 137 4.4 Adding remote interface methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 Methods inherited from javax.ejs.EJBObject . . . . . . . . . . . . . . . . . . . . 139 Using valid parameters and return values for Java RMI . . . . . . . . . . 140 4.5 Modifying, adding home methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 4.6 Generating Database Schema and mapping . . . . . . . . . . . . . . . . . . . . 141 The top-down approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 The bottom-up approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 The meet-in-middle approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 Creating the CMP sample database . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 Importing a database schema into VisualAge for Java . . . . . . . . . . . . 148 Defining a map between the EJBs and the database schema . . . . . . . 153 4.7 Adjusting the deployment descriptor attributes . . . . . . . . . . . . . . . . . 158 4.8 Generating your deployed code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 4.9 Adding Special Finder methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 Insert a finder method declaration in the CustomerHome interface . 161 Create a query string in the CustomerFinderHelper interface . . . . . . 161 4.10 Testing your Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 Chapter 5. Developing a Bean-managed persistence bean. . . . . 173 5.1 Bean-managed persistence Entity bean . . . . . . . . . . . . . . . . . . . . . . . . 173 5.2 The TransactionRecord Entity bean . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Creating the Entity bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Adding and defining BMP fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Understanding the Generated Methods . . . . . . . . . . . . . . . . . . . . . . . . 177 Modifying the Key Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Adding Remote Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Modifying and Adding Home Methods . . . . . . . . . . . . . . . . . . . . . . . . . 180 5.3 XML - The eXtensible Markup Language . . . . . . . . . . . . . . . . . . . . . . 182 Introduction to XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

The Document Object Model- DOM. . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 5.4 Persisting to an XML File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 Organizing the XML file. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Accessing the DOM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 Creating the Persister Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 5.5 Optimizing the Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 5.6 Specifying Environment Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 5.7 Transaction Management of the XML BMP . . . . . . . . . . . . . . . . . . . . 192 Chapter 6. Naming Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 6.1 System view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 6.2 Naming Service Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Location Service Daemon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Persistent Name Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 EJB Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 6.3 Using and Configuring Naming Service . . . . . . . . . . . . . . . . . . . . . . . . 199 Client looking for an object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Changing host name to Persistent Name Server and EJB server. . . . 205 Chapter 7. Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 7.1 Enterprise JavaBeans & Transactions. . . . . . . . . . . . . . . . . . . . . . . . . 212 The Bean-managed demarcation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 The Container-managed demarcation . . . . . . . . . . . . . . . . . . . . . . . . . . 213 The Transaction attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 Transaction Isolation Levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 7.2 EJB Transactions & CORBA OTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 CORBA OTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 Transactional vs Recoverable Objects . . . . . . . . . . . . . . . . . . . . . . . . . . 217 7.3 Implementing Session Synchronization . . . . . . . . . . . . . . . . . . . . . . . . 217 7.4 Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 Scenario Description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 The implementation model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 myTransactionTest.test1() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 myTransaction.test2( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 myTransaction.test3( ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 7.5 The test cases results. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Result tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Test scenarios results explanation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 Case 1: Effect of the TX_REQUIRED attribute. . . . . . . . . . . . . . . . 226 Case 2: Effect of the TX_MANDATORY attribute. . . . . . . . . . . . . . 227 Case 3: Effect of the TX_NOT_SUPPORTED attribute . . . . . . . . . 227 Case 4 and case 5: Effect of the TX_REQUIRES_NEW attribute . 228

vi

Developing Enterprise JavaBeans with VisualAge for Java

7.6 7.7 7.8 7.9

Case 6: Effect of the TX_SUPPORTS attribute . . . . . . . . . . . . . . . . 228 Concurrent access from multiple transactions. . . . . . . . . . . . . . . . . . . 228 Transactions and Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 Client-demarcated transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233

Chapter 8. Security. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 8.1 EJB Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 8.2 Identifying and Authenticating the Caller . . . . . . . . . . . . . . . . . . . . . . 236 8.3 Application Server Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Protecting resources by access control lists . . . . . . . . . . . . . . . . . . . . . 236 Users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 Realms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 Access control lists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Choosing authentication schemes and protocols . . . . . . . . . . . . . . . . . 240 About authentication protocols. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 About authentication schemes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 Combining authentication schemes and protocols . . . . . . . . . . . . . . . . 242

Part 2. Home Banking application . . . . . . . . . . . . . . . . . . . . . . . . . . .243


Chapter 9. Developing the Bank application . . . . . . . . . . . . . . . . . 245 9.1 Class Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 Chapter 10. Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 10.1 Problem description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 10.2 Relation package (itso.bank.ejb.relation) . . . . . . . . . . . . . . . . . . . . . . 251 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 Responsibilities of the Link classes . . . . . . . . . . . . . . . . . . . . . . . . . 252 Responsibilities of the bean developer . . . . . . . . . . . . . . . . . . . . . . . 252 Design Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Using the Link classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 Prerequisite (package itso.bank.ejb.base) . . . . . . . . . . . . . . . . . . . . 254 Naming conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 Using the ManyLink class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 Using the SingleLink class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 Description of the Link classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Class ManyLink. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Class SingleLink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263

vii

Chapter 11. Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 11.1 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 11.2 Requirements for the Inheritance. . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 11.3 Programming Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 Remote Interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 EJB Homes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 Primary Key Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 11.4 Mapping Schemes for Relational Databases . . . . . . . . . . . . . . . . . . . 268 11.5 Developing the BankAccount Hierarchy . . . . . . . . . . . . . . . . . . . . . . 270 Developing the Remote Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 The BankAccount Superclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 Developing Subclass EJBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 Proxy Superclass. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 Defining the Inheritance Mapping Scheme . . . . . . . . . . . . . . . . . . . . . 274 11.6 Accessing the BankAccount Hierarchy. . . . . . . . . . . . . . . . . . . . . . . . 275 The TypeConverter Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 11.7 Relationships and Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 SingleLink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 public BankAccount getBankAccount() . . . . . . . . . . . . . . . . . . . . . . 278 ManyLink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 public Enumeration getBankAccounts() . . . . . . . . . . . . . . . . . . . . . 279 public void addBankAccount(BankAccount acc) . . . . . . . . . . . . . . . 279 public void removeBankAccount(BankAccount acc) . . . . . . . . . . . . 279 public void removeAllMembers() . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 11.8 The Future of EJB Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 Chapter 12. Bank Implementation Entity Beans. . . . . . . . . . . . . . 281 12.1 Developing the BankAccount Hierarchy . . . . . . . . . . . . . . . . . . . . . . 282 Developing the BankAccount Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 Add the CMP Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 Modify the Generated Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 Add the Remote Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 Specify the Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 Developing the Children EJBs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 12.2 Developing the Bank Entity Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 Add Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 Add new methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 Modify the Generated Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 Add Methods to the Remote Interface . . . . . . . . . . . . . . . . . . . . . . . 289 12.3 Developing the Customer Entity Bean . . . . . . . . . . . . . . . . . . . . . . . . 290 Add Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 Add new methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292

viii

Developing Enterprise JavaBeans with VisualAge for Java

Modify the Generated Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 Add Methods to the Remote Interface . . . . . . . . . . . . . . . . . . . . . . . 295 Adding Finder Methods to CustomerHome . . . . . . . . . . . . . . . . . . . . . 295 12.4 Developing the TransactionRecord Entity Bean . . . . . . . . . . . . . . . . 296 Add Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 Add new methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Modify the Generated Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 Add Methods to the Remote Interface . . . . . . . . . . . . . . . . . . . . . . . 301 Adding Finder Method to TransactionRecordHome . . . . . . . . . . . . . . . 301 12.5 Creating the Bank Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 12.6 Creating the Bank Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Chapter 13. Bank implementation UserSB . . . . . . . . . . . . . . . . . . . 305 13.1 The UserSB sequence diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306 UserSB Customer Authentication Sequence Diagram. . . . . . . . . . . . . 306 UserSB Customer GetAccounts Sequence Diagram. . . . . . . . . . . . . . . 308 UserSB Customer Deposit Sequence Diagram . . . . . . . . . . . . . . . . . . . 309 UserSB Customer Withdraw Sequence Diagram . . . . . . . . . . . . . . . . . 310 UserSB Customer GetBalance Sequence Diagram . . . . . . . . . . . . . . . 310 UserSB Customer GetHistory Sequence Diagram . . . . . . . . . . . . . . . . 311 UserSB Customer Transfer Sequence Diagram . . . . . . . . . . . . . . . . . . 312 UserSB Customer PayBill Sequence Diagram . . . . . . . . . . . . . . . . . . . 313 13.2 Creating the UserSB Session Bean . . . . . . . . . . . . . . . . . . . . . . . . . . 314 Add Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 Add New Methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 Modify the Generated Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 Add Methods to the Remote Interface . . . . . . . . . . . . . . . . . . . . . . . . . . 328 Generate Deployed Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 Chapter 14. Bank Implementation AdminSB . . . . . . . . . . . . . . . . . 331 14.1 Developing the AdminSB Session Bean . . . . . . . . . . . . . . . . . . . . . . . 331 Add Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332 Add new methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 Modify the Generated Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 Add Methods to the Remote Interface . . . . . . . . . . . . . . . . . . . . . . . . . . 339 Generate Deployed Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339

Part 3. APPENDIXES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .341


Appendix A. Hints and Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 A.1 Importing EJBs from a Jar File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 A.2 Moving or Copying EJBs Between Repositories . . . . . . . . . . . . . . . . . 349 A.3 Updating WebSphere Class Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350

ix

A.4 Starting and Stopping WebSphere Advanced Edition 2.0 . . . . . . . . . 351 Appendix B. Transaction Samples Appendix . . . . . . . . . . . . . . . . . 353 B.1 Installing and running the transaction samples . . . . . . . . . . . . . . . . . 353 Creating the DB2 database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 Importing the transaction.dat repository . . . . . . . . . . . . . . . . . . . . . . . 354 Adding the TransactionSamples project to the workspace . . . . . . . . . 354 Generating the deployed code and running the samples . . . . . . . . . . . 355 B.2 Output Samples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 Appendix C. ITSOBANK database . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 C.1 database Definition DDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 C.2 Sample Data of ITSOBANK Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 Appendix D. Samples and BANK Application . . . . . . . . . . . . . . . . 373 Appendix E. Special Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 Appendix F. Related Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . 383 F.1 International Technical Support Organization Publications . . . . . . . 383 F.2 Redbooks on CD-ROMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384 F.3 Other Publications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384 How to Get ITSO Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385 How IBM Employees Can Get ITSO Redbooks. . . . . . . . . . . . . . . . . . . . . . 385 How Customers Can Get ITSO Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . 386 IBM Redbook Order Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 List of Abbreviations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 ITSO Redbook Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 6:56 pm

5429LOF.fm

Figures
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. SanFrancisco basic architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 SanFrancico future model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Global Enterprise JavaBeans View from Client and Server . . . . . . . . 17 The TransferBean class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 The business methods of the TransferBean class . . . . . . . . . . . . . . . . . 27 The ejbCreate method of the TransferBean class . . . . . . . . . . . . . . . . . 29 Implementing the SessionBean interface in the TransferBean class . 31 The TransferHome home interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 The Transfer remote interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 VisualAge for Java main window. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 EJB Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Adding a new EJB Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 EJB Page After the Creation of the New Group . . . . . . . . . . . . . . . . . . 39 Create EJB SmartGuide. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Create ReadCustomerInfo EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Adding Import Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 EJB Workspace after the Creation of the New EJB . . . . . . . . . . . . . . . 45 Create Field smartguide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 Create fileName Field. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Create Method smartguide. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Create Method SmartGuide - First Page . . . . . . . . . . . . . . . . . . . . . . . . 51 Create Method SmartGuide - Second Page . . . . . . . . . . . . . . . . . . . . . . 52 RaedCustomerInfoBean in the EJB Workspace . . . . . . . . . . . . . . . . . . 55 Properties Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Environment Properties Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Environment Properties Page after Definition of a Property . . . . . . . . 60 Definition of the Properties Field. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Getting Properties from the Context . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Retrieve Environment Variable Value from Properties . . . . . . . . . . . . 61 Method properties Window. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Method Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Modify Method Control Descriptor Window . . . . . . . . . . . . . . . . . . . . . 63 EJB WorkSpace after the EJB Deployment Code Generation . . . . . . . 65 Generate Test Client. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 EJB Server Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Location Service Properties Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Persitent Name Service Property Dialog. . . . . . . . . . . . . . . . . . . . . . . . 70 EJB Server Properties Dialog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Copyright IBM Corp. 1999

xi

5429LOF.fm 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81.

Draft Document for Review April 14, 1999 6:56 pm

Console After all Servers are Started. . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Connect Window for the ReadCustomerInfo Session Bean . . . . . . . . . 75 Home Test Client Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Remote Test Client Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 Testing Remote Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 Inspector Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Read Customer Client Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Exporting .jar Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Export to an EJB jar File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Export to an EJB Client jar File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 IBM WebSphere Application Server Administration Login . . . . . . . . . 92 Container Page inside WebSphere. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Deploy Jar File Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Redeployment Selection window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 EJB Jar Copy Window. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 Exporting to EJB Jar files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 Undeploy Jar file window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 EJB Jar Undeploy Result Window. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 WebSphere Navigation Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 The jet Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 jet Tool Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 The jet Tool after Importing the ReadCustomerInfo Bean. . . . . . . . . 103 Using Jet Tool to Modify a Property Value . . . . . . . . . . . . . . . . . . . . . 104 The SmartGuide Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Project not Found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Create EJB SmartGuide. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 EJB Class Attributes and Interfaces Definition . . . . . . . . . . . . . . . . . 115 Customer CMP Entity Bean Generated Classes. . . . . . . . . . . . . . . . . 117 Association between EJB Reserved Package and Project. . . . . . . . . . 119 Association between EJB Class package and Project . . . . . . . . . . . . . 120 CustomerCMP Entity Beans Fields . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Create Field SmartGuide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 New Fields Created. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 CMP Fields Icon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Dummy Member Field Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 Workbench without Dummy Field . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 Transient Field Modifier Utilization Example . . . . . . . . . . . . . . . . . . 130 Methods added to the Remote Interface are identified by an Icon . . 139 Remote Interface generated Methods . . . . . . . . . . . . . . . . . . . . . . . . . 139 Association Between CMP Fields and Database Columns . . . . . . . . . 142 Selection with Schema Browser: Database, Tables, Converters . . . . 143 With Map Browser Associate Fields and Columns . . . . . . . . . . . . . . . 144 EJB Server Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

xii

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 6:56 pm

5429LOF.fm

82. Characteristics of DB2 Table and Columns Created for CMP Fields 146 83. Schema Browser Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 84. Database Connection Info Window VisualAge for Java . . . . . . . . . . . 150 85. Select Tables Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 86. Schema Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 87. Column Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 88. CustomerSchema class Created After Saving the Schema. . . . . . . . . 153 89. Map Browser Window. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 90. New Datastore Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 91. Map Browser Window with Customer Table Map . . . . . . . . . . . . . . . 155 92. Property Map Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 93. Customer Property Map Editor Window. . . . . . . . . . . . . . . . . . . . . . . 157 94. CMPSMap class Created After Saving the Map . . . . . . . . . . . . . . . . . 157 95. Properties Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 96. Checking Your Server is Ready . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 97. Running the Test Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 98. Customer EJB Test Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 99. Customer Home Interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 100. CustomerKey Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 101. Customer Remote Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 102. Customer getName() Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 103. New CustomerKey Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 104. Retrieve Dessureault Customer instance Using FindByLastName. . 171 105. The Create EJB SmartGuide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 106. The Create Field SmartGuide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 107. The Generated Methods and Classes. . . . . . . . . . . . . . . . . . . . . . . . . . 178 108. Mapping Entity Beans to an XML File . . . . . . . . . . . . . . . . . . . . . . . . 184 109. Document Type Definition (DTD) for the TransactionRecord . . . . . . 185 110. The Document Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 111. Setting an Environment Property in the Deployment Descriptor . . . 192 112. JNDI Architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 113. WebSphere Advanced Edition 2.0: System View . . . . . . . . . . . . . . . . 197 114. Creating the InitialContext Object . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 115. Changing the Boot Port Value in WebSphere Advanced Edition 2.0. 201 116. Creating the EJBHome object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 117. Changing the JNDI Name under VisualAge for Java. . . . . . . . . . . . . 203 118. Changing the JNDI Name with Jet Tool . . . . . . . . . . . . . . . . . . . . . . . 204 119. Creating the EJB Object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 120. Accessing an EJB from a Different Machine . . . . . . . . . . . . . . . . . . . . 206 121. Opening the EJB Server Configuration. . . . . . . . . . . . . . . . . . . . . . . . 206 122. EJB Server Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 123. Persistent Name Server Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 124. Location for Persistent Naming Information . . . . . . . . . . . . . . . . . . . 208

xiii

5429LOF.fm

Draft Document for Review April 14, 1999 6:56 pm

125. EJB Server Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 126. OTS Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 127. SimpleClient Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 128. MyTransactionTest.test1() method . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 129. MyTransactionTest.test2() Method . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 130. MyTransactionTest.test3() Method . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 131. Access Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 132. System View of the Bank Application . . . . . . . . . . . . . . . . . . . . . . . . . 246 133. Bank Application Class Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 134. Single-table mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 135. Root/leaf mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 136. Distinct-table mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 137. BankAccount Inheritance Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . 270 138. Simulating Inheritance by delegation . . . . . . . . . . . . . . . . . . . . . . . . . 272 139. Mapping the BankAccount Hierarchy to the Database . . . . . . . . . . . 274 140. UserSB Customer Authentication Sequence Diagram . . . . . . . . . . . . 307 141. UserSB GetAccounts Sequence Diagram . . . . . . . . . . . . . . . . . . . . . . 308 142. UserSB Deposit Sequence Diagram. . . . . . . . . . . . . . . . . . . . . . . . . . . 309 143. UserSB Withdraw Sequence Diagram. . . . . . . . . . . . . . . . . . . . . . . . . 310 144. UserSB getBalance Sequence Diagram . . . . . . . . . . . . . . . . . . . . . . . . 311 145. UserSB getHistory Sequence Diagram . . . . . . . . . . . . . . . . . . . . . . . . 312 146. UserSB transfer Sequence Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . 313 147. UserSB PayBill Sequence Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . 314 148. Properties for the UserSB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 149. UserSB generetaed code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 150. Import from an EJB Jar File window . . . . . . . . . . . . . . . . . . . . . . . . . 346 151. Import from CreateCustomerInfo EJB Jar File . . . . . . . . . . . . . . . . . 347 152. EJB Workspace after Importing and EJB .jar . . . . . . . . . . . . . . . . . . 349 153. WebSphere Application Server Java Engine Setup . . . . . . . . . . . . . . 350 154. ITSOEJBSamples EJB Group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 155. ITSOBANK Database Data Definition Language (Part1) . . . . . . . . . 366 156. ITSOBANK Database Data Definition Language (Part 2) . . . . . . . . . 367 157. ITSOBANK Database Data Definition Language (Part 3) . . . . . . . . . 368 158. ITSOBANK Data (Part 1). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 159. ITSOBANK Data (Part 2). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 160. ITSOBANK Data (Part 3). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 161. ITSOBANK Data (Part 4). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 162. SG24-5429 Directory Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373

xiv

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 6:56 pm

5429LOT.fm

Tables
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. Container-Managed fields mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 Creating the Different DOM Nodes in the hierarchy. . . . . . . . . . . . . . 187 Accessing the Different DOM Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Scenario 1 - TX_REQUIRED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Scenario 2 - TX_MANDATORY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 Scenario 3 TX_NOT_SUPPORTED . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 Scenario 4 TX_REQUIRES_NEW . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 Scenario 5- TX_REQUIRED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 Create Field bankName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 Create Field customerLink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Create Field accountLink. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Create Fields for the Customer Bean . . . . . . . . . . . . . . . . . . . . . . . . . . 291 Create Field bankAccountLink . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 Create Field bank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 Create Field accountId and traccId . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Create Field transamt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Create Field transamt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Create Field accountLink. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Create Bank Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Create Bank Datastore Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Bank Table Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 Bank Property Map Relationship . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 Create Field bankAccountHome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 Create Field bankHome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 Create Field custKey . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 Create Field customerHome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 Create Field customerRef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 Create Field initialCtx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 Create Field loginPassword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 Create Field loginStatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 Create Field transactionRecordHome . . . . . . . . . . . . . . . . . . . . . . . . . . 319 Create Field for AdminSB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332

Copyright IBM Corp. 1999

xv

5429LOT.fm

Draft Document for Review April 14, 1999 6:56 pm

xvi

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429pref.fm

Preface
With the introduction of the Enterprise JavaBeans specification, application developers can now focus on writing the business logic necessary to support their application without having to deal with the intricacies of the underlying middleware which still gives crucial services such as transactions, security, naming and persistency. IBM is exploiting this specification in a family of compatible Java application servers conforming to IBMs Enterprise Server for Java (EJS) specification. In addition, IBM has already introduced the support for EJB development into its awarded Java development tool: VisualAge for Java version 2.1. By Including in this new version the EJS runtime, VisualAge for Java provides a unique Rapid Application Development environment to develop, debug and test EJBs. In this book we explore in depth the EJB specification and apply this knowledge to develop an application including all different facets of EJB: Session bean, Bean-Managed, Container-Managed persistence entity beans, transaction (JTS), security, naming service (JNDI). We also address relationships and inheritance which are issues not yet addressed by Enterprise JavaBeans specification.

The Team That Wrote This Redbook


This redbook was produced by a team of specialists from around the world working at the International Technical Support Organization San Jose Center. Joaquin Picon is a consultant at the International Technical Support Organization, San Jose Center. He writes extensively and teaches IBM classes worldwide on application development, object technology, CORBA and Enterprise JavaBeans. Before joining the ITSO, Joaquin worked at the IBM Application Enabling Center Of Competency in France. Joaquin holds a degree in telecommunications from the Institut National de Telecommunications (http://www.int-evry.fr). Patrizia Genchi is a I/T Specialist in IBM Italy.She have been working for IBM for nine years. She have been involeved in networking projects for six years working for the ctual Tivoli lab in Rome. She now works for the Java Technology Center of the IBM Semea Sud . She has 3 years of experience in

Copyright IBM Corp. 1999

xvii

5429pref.fm

Draft Document for Review April 14, 1999 3:55 pm

developing JAVA applications.She has worked as a SanFrancisco Technical consultant in the last 2 years. She holds a degree in Mathematics from the University of Bari. Martin Weiss is an Advisory IT Specialist in Switzerland. He has been with IBM since 1978, working in application development (IBM mainframe, AS/400, OS/2, Windows NT). Since 1993 he has focused on object technology, primary as a developer and mentor in VisualAge customer projects (Smalltalk, C++, Java). Maneesh Sahu is a software engineer in IBM, Bangalore. He has 2 years of experience in developing JavaBeans. He holds a degree in computer engineering from Karnataka Regional Engineering College (http://www.krec.ernet.in). His areas of expertise include developing visually wirable components, application development in VAJava and XML. He has written extensively on Developing Java and XML applications. Alain Dessureault is an IT Architect in IBM Canada. He has 7 years of experience in all phases of the software life cycle (analysis, requirements, architecture, design, construction, implementation and testing). He/she holds a degree in Computer Science from the Universite Laval. His/her areas of expertise include object-oriented tools processes and languages, distributed systems and client-server systems architecture, design and programming He has written extensively on Systems architecture and Distributed computing.

Acknowledgments
This book would not have been possible without the help of the following people who contributed to the content of the book: The editing team, and staff at the International Technical Support Organization, San Jose Center. Dave Ings, Howard Borenstein VisualAge for Java Development, IBM Toronto Lab, Toronto Graeme Dixon, Keith Uher WebSphere Advanced Edition 2.0 Development, IBM Transarc, Pittsburgh Elias Bayeh WebSphere Advanced Edition 2.0 Development, IBM Raleigh Lab, Raleigh Verlyn Johnson, San Francisco Marketing Support, IBM Rochester

xviii

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429pref.fm

David S. Linthicum, Chief Technology Officer, SAGA, http://www.sagus.com Chris Crenshaw, President, Nova Laboratories, http://www.nova-labs.com

Comments Welcome
Your comments are important to us! We want our redbooks to be as helpful as possible. Please send us your comments about this or other redbooks in one of the following ways:
u Fax the evaluation form found in ITSO Redbook Evaluation on page 403

to the fax number shown on the form.


u Use the electronic evaluation form found on the Redbooks Web sites:

For Internet usershttp://www.redbooks.ibm.com For IBM Intranet usershttp://w3.itso.ibm.com


u Send us a note at the following address: redbook@us.ibm.com

xix

5429pref.fm

Draft Document for Review April 14, 1999 3:55 pm

xx

Developing Enterprise JavaBeans with VisualAge for Java

Part 1

Enterprise JavaBeans: essentials

Copyright IBM Corp. 1999

Developing Enterprise JavaBeans with VisualAge for Java

1 Moving business logic to Enterprise JavaBeans


With the introduction of the Enterprise JavaBeans specifications, we have another new model for creating and packaging business logic. But having a new technology does not mean it has to be used in any situation.

1.1 Stand-alone application


If you are going to develop an application running on a single workstation for a single user, you may consider using the Java language but you can certainly ignore Enterprise JavaBeans.

Copyright IBM Corp. 1999

1.2 High volume transactions


At the other end of the spectrum, you are currently or plan to run high volume transactions application. In that case, you are already using for years or should start using CICS mainframe software which manages transactions like selling and shipping products, billing customers and trading stocks. As businesses are adopting the Internet, the number of electronic transactions is exploding and only application servers like CICS can provide the kind of reliability and scalability required by mission critical applications. While workstation based NT system are looking to be able to support around 1500 concurrent users by end of 1999, CICS is used to handle as many as 250000 concurrent users at a time. In addition to using sophisticated technologies, such as Parallel Sysplex, with resource managers sharing data across the sysplex providing high availability, CICS business transaction services (BTS) allow to control complex business transactions. Using BTS, a top-level program manages the inter-relationship, ordering parallel execution, commit scope, recovery and restart of the actions that make up the business transaction. If this environment describes your requirements for running your application, then it is too early to look at Enterprise JavaBeans.

1.3 San Francisco application frameworks


Assuming your application does not have these high transaction volume constraints, you may be looking to commercial application frameworks. This may be the solution, for a particular domain, to speed up your application development. A significant group of business management systems capabilities are common within a particular application domain. These capabilities support the core business activities (processes) performed by any business within this domain. For instance, the amount of overlap among various implementations of General Ledger is significant. Therefore, building an application from scratch means that a large percentage of the total investment goes into building standard components rather than into creating new components that represent added value. These considerations led to the idea of commercial application frameworks, which are a set of classes representing business entities that cooperate to

Developing Enterprise JavaBeans with VisualAge for Java

implement core business processes. The availability of object-oriented frameworks allows developers to rely on a base of existing business processes and business objects. SanFrancisco Application Business Components is the answer IBM gives to this requirement. It is a set of components that address commercial area such as General Ledger (GL),Account Payable/Account Receivable(AR/AP) Warehouse Management(WM), Order Management (OM). SanFrancisco has a strong technological infrastructure and has a layered architecture that shields developers from implementation details of function such as distributed computing and transaction management. The SanFrancisco architecture is made of three integrated layers:

Foundation Common Business Objects (CBOs) Core Business Processes(CBPs) The architecture is illustrated in figure 5

Figure 1. SanFrancisco basic architecture.

The Foundation layer is the core technological layer of SanFrancisco and provides the fundamental services such as distributed object creation,

Moving business logic to Enterprise JavaBeans

synchronization, persistence, and a consistent application development model. It encapsulates the technological aspects of cross-platform distributed object management and provides an easy-to-use API. It also includes support for security, provides distributed transaction processing, and forms a middleware between a client application and server. The CBOs layer is built on top of the Foudation layer. It provides advanced components like Company,Address,BusinessPartner which are common across business domain. It provides generalized mechanisms to be used to solve business application problems Core Business Processes are the top layer of SanFrancisco. This layer provides the fundamental behavior and structure for particular domains. San Francisco provides the behaviors and structures needed to allow developers to customize the Core Business Processes for use in their applications. For example, SanFrancisco contains the General Ledger Core Business Process, which includes the architecture, design, and default logic to build a General Ledger application. The developer, instead of building it from scratch, needs only to enhance and extend this layer to build a customized General Ledger application. (For details you can refer to the following redbook SG242157-00 -San Francisco Concepts & Facilities ). Building application with SanFrancisco make the developer to be concentrated only on the business need without taking care of technological issue like distributing computing. Today the SanFrancisco Foundation overlaps the functions provided by EJB servers. It also provides a programming model which includes functions not yet addressed by EJB. On the other hand, EJB servers include some functions not provided by SanFrancisco. For example CORBA access is not delivered by SanFrancisco because SanFrancisco doesnt support IIOP access. You can integrate SanFrancisco business components with emerging technologies such as Websphere, but components built for one environment will not automatically run in the other. If you want to build a GL application which is CORBA compliant you may choose to build your own EJB components but it has to be clear that in this case you have to write 100% of your business code. You can not use the SanFrancisco business components as the starting point for a CORBA compliant application IBM has announced it plans to migrate the SanFrancisco business components to run on the Websphere family of servers. The SanFrancisco programming model will be migrated to the EBJ model. This will provide CORBA access to SanFrancisco components. The Websphere family of EJB

Developing Enterprise JavaBeans with VisualAge for Java

servers will be enhanced to provide the functions needed by the new version of the SanFrancisco components. With this new version you will be able to decide if you application is going to run in a EJB server or in a SanFrancisco server as depicted by Figure 2

Figure 2. SanFrancico future model

1.4 Distributed Object-Oriented Technologies


The growth of Object-Oriented technologies have facilitated the creation of standards providing the frameworks necessary to develop within a 3-tier architecture. The Object Management Group (OMG) defined the Common Object Request Broker Architecture (CORBA) standard in 1991 to help vendors developing applications which can cooperate in a networking environment. Microsoft did the same in its Distributed Common Object Model (DCOM).

Microsoft DCOM
The Distributed Component Object Model (DCOM) is Microsofts solution to distributed object architectures. It uses Object Remote Procedure Calls (ORPCs) to carry messages between components. Key features engineered into the DCOM architecture include language independence, transport

Moving business logic to Enterprise JavaBeans

neutrality, and static and dynamic object method invocation. Because DCOM supports Windows platforms, DCOM-based applications can take full advantage of existing Microsoft services such as security and transactions. Some vendors are migrating DCOM to other platforms such as UNIX, and DCOM eventually will become truly cross-platform. One thing is clear, Enterprise JavaBeans have no place in this environment.

CORBA
In the recent years, several companies have put on the market products supporting the CORBA standard. There is no doubt that CORBA offers the most mature environment for distributed objects. Even though not a single vendor provides the entire set of object services, they still offer the largest set of services necessary to run such distributed object oriented applications. In addition, with a product like Component Broker, developers dont need to know how to program persistence, security, or transactional integrity, because the appropriate code is generated for them. IT organizations can, therefore, develop their business logic, then select the qualities of service necessary for the deployment of the business application. This idea of separating deployment concerns from actual business logic is built in Component Broker from the very beginning. However, the contract between Component Brokers business objects and the containers in which they are executed has not been standardized. Such a contract between business objects and their containers has been standardized in the form of the Enterprise JavaBeans specification. This specification opens a new world of opportunities for tool builders, ranging from those who build high-end enterprise-class tools to IDE tools vendors who simplify the creation, assembly and reuse of components during development and deployment.

1.5 Summary
The Enterprise JavaBeans specification help significantly in the separation of business logic from the middleware intricacies of dealing with major services like persistence, transaction, naming and security. If it is not yet the technology you can start using in any situation, this may change very quickly. As we have seen major commercial frameworks, CORBA

Developing Enterprise JavaBeans with VisualAge for Java

and high transaction volume environments have in their plan to support soon Enterprise JavaBeans. Developing business logic in the form of Enterprise JavaBeans may give a complete platform independence and for the first time a unique capability to move from workstation to more reliable, secure and scalable mainframe environments by the magic of a re-deployment. Before we start looking on how to develop Enterprise JavaBeans with VisualAge for Java, we propose to refresh your mind with a quick description of the major components and roles found in the Enterprise JavaBeans specification.

Moving business logic to Enterprise JavaBeans

10

Developing Enterprise JavaBeans with VisualAge for Java

2 Enterprise JavaBeans: Quick Start


Since the March 1998 announcement of the Enterprise JavaBeans (EJB) 1.0 specification, most of the companies already involved in CORBA, transaction monitors, or databases have announced that their products will implement the specification. The Enterprise JavaBeans specification provides a solution for a clear separation of the business logic and the intricacies of dealing with persistency, transactions, and other middleware-related services. Now you can create applications and concentrate exclusively on the business logic packaged as EJBs. The difficult part of dealing with all other services required by applications is provided by a container framework in which EJBs are deployed and executed. Clients of EJBs are of course new EJB clients using Remote Method Invocation (RMI) and Java Naming and Directory Interface (JNDI) services.

Copyright IBM Corp. 1999

11

However, CORBA clients written in C++, as ActiveX, or in Java can be EJB clients as well. By using CORBA services, a CORBA client can have full access to EJBs.

2.1 Roles
The separation of the business logic from other tasks requires the definition of different roles.

Provider
The Enterprise JavaBeans provider is the developer who understands the business logic and knows how to translate it into Java code. The Enterprise JavaBeans provider needs to have an understanding of the interfaces and semantics of Enterprise JavaBeans. The Enterprise JavaBeans provider is responsible for deciding, among other issues, whether the enterprise Bean is persistent or not. If the enterprise Bean is persistent, the enterprise Beans provider must provide a list of fields with persistent state. The enterprise Bean provider also must decide whether he or she is going to manage the persistency, using such support as files, databases, or CICS transactions, or let the container manage the persistency. Another decision the enterprise Beans provider must make concerns the behavior of the enterprise Bean when it is involved in the scope of a transaction.The Enterprise JavaBeans providers responsibility ends with the packaging of the EJB and all associated files as a jar file, which is then given to the deployer.

Deployer
The deployer is responsible for installing the EJB classes in the EJB server. The deployer understands EJB and the runtime server environment and can map EJB developer requirements and configure them using EJB server tools. The deployer also must ensure that EJBs are accessible through JNDI.

Application Assembler
The application assembler writes applications that use EJBs. He or she has a client view of the EJB and can create new, composed EJBs and develop applets, servlets, or native CORBA applications that use EJBs.

12

Developing Enterprise JavaBeans with VisualAge for Java

Container Provider
The container provider focuses mainly on providing scalability, security, and transactional behavior for EJBs. The accompanying tools generate the "glue" code that creates the link between the business logic and the underlying services. The container intercepts client calls to the EJB and executes the appropriate services that ensure the transactional, persistent behavior expected for the EJB.

Server Provider
The server provider brings operating system and middleware services to the container. In most cases, the same vendor provides the server and container because there are as yet no specifications to define the interface between a container and a server.

System Administrator
The system administrator ensures that the system is working properly by using the monitoring and management tools provided by the server and container providers.

2.2 Components
In this section we present an overview of the major Enterprise JavaBeans components.

Container
A container is where an EJB lives. It can contain one or more EJB classes. These classes are identified by their home interface, which acts like a factory that allows clients to create, find, and remove instances of an EJB. By using the Deployment Descriptor during EJB development, or later on by using deployment tools, it is possible to give a meaningful name to the home interface. The container places this name in the naming space that is accessible from clients using JNDI.

Session and Entity JavaBeans


There are two types of Enterprise JavaBeans:

Enterprise JavaBeans: Quick Start

13

u Session beans u Entity beans

Session Beans
The life time of a session bean is typically that of its client. A session bean contains conversational states that are not persistent and will not survive a server failure. However, a session bean must indicate to its container a state management mode: STATELESS STATEFUL In order for a container to manage efficiently a large number of bean instances, it can take an instance out of memory and store it in permanent storage. This is called passivation. When this bean is invoked again, the container creates a new instance and initializes it with the data saved during passivation. This is called activation. Therefore, if the session bean contains a conversational state that must be preserved between method invocations, the session bean indicates STATEFUL management mode. Otherwise the container considers the session bean STATELESS and never uses passivation but instead can destroy it in case of memory resource shortage. Because all instances of stateless session beans are the same, the container can decide to use any available instance to satisfy a client request.

Entity Beans
Entity beans are used to represent persistent data. In the most common case, their fields are mapped into a relational database. But in more complex situations, the persistent data can result from the invocation of an application or the execution of an existing CICS transaction. The persistent state of an entity bean is defined in two flavors: 1. Bean-managed persistence (BMP) With a BMP entity bean, the EJB provider manages the persistent state of the bean by coding database calls or any type of access to permanent storage. It is the provider responsibility to save and restore the state of the EJB when called by the container on such methods as: ejbFind, ejbLoad, and ejbStore. A BMP entity bean is inappropriate for large applications. This becomes obvious when you think about a large number of entity beans, each accessing a given database. For portability and scalability use a Container-managed persistence entity bean.

14

Developing Enterprise JavaBeans with VisualAge for Java

2. Container-managed persistence (CMP) With Container-managed persistence entity beans you do not have to know which source is used to provide the persistent state of the bean. You just have to specify which fields are persistent. Thus there is complete portability, and the EJB provider can focus on the business logic. The hard part is for the container. Each container provider also provides the tools to map EJB fields to databases or any existing application. In addition, it can efficiently manage database access by using a shared pool of connections and caching data. Vendors will differentiate their offerings by the number of containers they provide to access different sources, and the reliability and scalability of their implementation. When Container-managed persistence is used, an Enterprise JavaBeans can be transparently moved from one container to another regardless of whether it is provided by the same vendor. The business logic remains untouched! Every Enterprise JavaBeans entity bean has a unique identity within its home. Its identity is defined by a primary key. The primary key can be any class type. The only restriction is that the class must implement serializable, because it must be possible to pass the primary key between the client and the server. The primary key is used by the client to create or find an instance of an EJB.

2.3 An Overall Picture


Without going into deep detail, let us look at how the major components relate to each other from a developers perspective. Let us assume you want to develop the EmployeeID EJB. You first have to buy an EJB server with appropriate containers supporting the source of the persistency of your data. With the containers, the vendor must also provide tools to deploy your EJB packaged in jar files. Assuming you have all this, you can start developing your EJBs. For each EJB you need to decide whether it is a session or an entity bean. If it is a session bean, you have to inform its container about its management mode: STATEFUL or STATELESS. For an entity bean with maximum portability, scalability, and reliability, select a CMP bean. Otherwise

Enterprise JavaBeans: Quick Start

15

implement it as a BMP. But dont forget that mixing persistency state management with business logic is not good for portability. For each bean, you have to provide an implementation, additional classes, and interfaces. Assuming that your bean name is EmployeeID, you have to: 1. Develop an EmployeeIDBean class 2. Develop an EmployeeID interface 3. Develop an EmployeeIDHome interface 4. If it is an entity bean, provide an EmployeeIDKey 5. Create a deployment descriptor file 6. Create a manifest file 7. Package all of these files inside a deployment jar that the container deployment tool uses to install and execute the EJBs. The information set in the deployment descriptor contains the beanHomeName. This is the JNDI name you give to the EmployeeIDHome. It can be any name that makes sense in your organization, such as applications/travelExpenses. At deployment time, the deployer can still change it. When the container instantiates the EJB home, it registers in the naming space this name bound to EmployeeIDHome (see Figure 3 on page 17). Later on, an EJB client uses the JNDI API to look up the home and then continues by creating, finding, or removing instances of the object managed by its home.

16

Developing Enterprise JavaBeans with VisualAge for Java

Figure 3. Global Enterprise JavaBeans View from Client and Server

One of the major benefits of EJB comes from the separation of the business logic from the middleware supporting it. The specification also defines the contract with the container provider who provides such services as transactions, persistency, and security and the tools to generate the glue code that realizes the link between these services and the business logic. To make the EJB offering even more attractive, VisualAge for Java 2.1 comes with complete EJB development support, including WebSphere 2.0 runtime. You can now develop your EmployeeIDBean and let the tool generate every thing else including the container deployment classes. You can develop, debug, and test any type of EJBs: session beans, BMP entity beans, or CMP entity beans. VisualAge for Java also generates the jar file with all information required to deploy it in containers such as WebSphere, Component Broker, or any other vendor container. All these capabilities are detailed in this book.

Enterprise JavaBeans: Quick Start

17

18

Developing Enterprise JavaBeans with VisualAge for Java

3 Developing a Session bean


3.1 Session Beans Basics
Session beans support is mandatory for an EJB 1.0 specification compliant container. Session beans are transient objects that exist for the duration of a single user session. A session represents work in progress on behalf of a single client. In this chapter, we look to what needs to be implemented by a developer, how he deploys, debug and test a session bean.

Basic Components of a Session Bean


Every session bean must have the following components:
u Bean class

This class encapsulates the data associated with the enterprise bean and contains the developer-implemented business methods that access this data. It also contains the methods used by the container to manage the life cycle of an enterprise bean instance. Clients (whether they are other

Copyright IBM Corp. 1999

19

enterprise beans or user applications) never access objects of this class directly; instead, they use the container-generated classes associated with the home and remote interfaces to manipulate the enterprise bean.
u Home interface

This interface contains the methods used by the client to create and remove instances of the enterprise bean. This interface is implemented by the container during enterprise bean deployment in a class known generically as the EJB home class.
u Remote interface

Once the client has used the home interface to gain access to an enterprise bean, it uses this interface to invoke the business methods defined in the bean class. This interface is implemented by the container during enterprise bean deployment in a class known generically as the EJB object class. Unlike an entity bean, a session bean does not have a primary key class. A session bean does not require a primary key class because instances of session beans cannot be uniquely identified from each other.

Stateless Versus Stateful Session Beans


Session beans encapsulate data and methods associated with a user session, task, or ephemeral object. By definition, the data in a session bean instance is ephemeral; if it is lost, no real harm is done. For example, at a bank, a session bean might represent a funds transfer, the creation of a customer profile or new account, and a withdrawal or deposit. If a fund transfer is being typed in when a server crashes, the data associated with the bank accounts involved always remains consistent. Only the transfer data is lost, which can always be retyped. The manner in which a session bean is designed determines whether its data is shorter lived or longer lived:
u If a session bean needs to maintain specific data across methods, it is

referred to as a stateful session bean. When a session bean maintains data across methods, it is said to have a conversational state. A Web-based shopping cart applet is a classic example of a stateful session bean. As the shopping cart user adds (and subtracts) items to the shopping cart, the underlying enterprise bean must maintain a record of the content of the cart. Once a particular client begins using an instance of a stateful session bean, the client must continue to use that instance as long as the specific state of that instance is required. If the bean is lost before the contents of the shopping cart is committed to an order, the shopper must load up a new shopping cart.

20

Developing Enterprise JavaBeans with VisualAge for Java

u If a session bean does not need to maintain specific data across methods,

it is referred to as a stateless session bean. The example Transfer enterprise bean developed in The TransferBean class on page 25 provides an example of a stateless session bean. For stateless session beans, a client can use any instance to invoke any of the session beans methods.

Session Bean Life Cycle


This section describes the life cycle of a session bean instances. Differences between stateful and stateless session beans are noted.

Creation state
A session beans life cycle begins when a client invokes a create method defined in the beans home interface. In response to this method invocation, the container does the following: 1. Creates a new memory object for the session bean instance. 2. Invokes the session beans setSessionContext method. (This method passes the session bean instance a reference to a session context interface that can be used by the instance to obtain container services and get information about the caller of a client-invoked method.) 3. Invokes the session beans ejbCreate method corresponding to the create method called by the client.

Ready state
Once a session bean instance is created, it moves to the ready state of its life cycle. In this state, clients can invoke the beans business methods defined in the remote interface. The actions of the container at this state are determined by whether a method is invoked transactionally or nontransactionally:
u Transactional method invocations

When a client invokes a transactional business method, the session bean instance is associated with a transaction. Once a bean instance is associated with a transaction, it remains associated until that transaction completes. (Furthermore, an error results if a client attempts to invoke another method on the same bean instance if invoking that method causes the container to associate the bean instance with another transaction or with no transaction.) The container then invokes the following methods: 1. The afterBegin method, if that method is implemented by the bean class.

Developing a Session bean

21

2. The business method in the bean class that corresponds to the business method defined in the beans remote interface and called by the client. 3. The bean instances beforeCompletion method, if that method is implemented by the bean class and if a commit is requested prior to the containers attempt to commit the transaction. The transaction service then attempts to commit the transaction, resulting either in a commit or a rollback. When the transaction completes, the container invokes the beans afterCompletion method, passing the completion status of the transaction (either commit or rollback). If a rollback occurs, a stateful session bean can roll back its conversational state to the values contained in the bean instance prior to beginning the transaction. Stateless session beans do not maintain conversational state, so they do not need to be concerned about rollbacks.
u Nontransactional method invocations

When a client invokes a nontransactional business method, the container simply invokes the corresponding method in the bean class.

Pooled state
The container has a sophisticated algorithm for managing which enterprise bean instances are retained in memory. When a container determines that a session bean instance is no longer required in memory, it invokes the bean instances ejbPassivate method and moves the bean instance into a reserve pool. When this method returns, the container saves the instances state to a data source. A session bean instance cannot be passivated when it is associated with a transaction. If a client invokes a method on a passivated session bean instance, the container activates the instance by restoring the instances state from the data source and then invoking the bean instances ejbActivate method. When this method returns, the bean instance is again in the ready state. Because every stateless session bean instance of a particular type is the same as every other instance of that type, stateless session bean instances are not passivated or activated. These instances exist in a ready state at all times until their removal.

Removal state
A session beans life cycle ends when a client or the container invokes a remove method defined in the beans home interface and remote interface. In response to this method invocation, the container calls the bean instances ejbRemove method.

22

Developing Enterprise JavaBeans with VisualAge for Java

If you attempt to remove a bean instance while it is associated with a transaction, the javax.ejb.RemoveException is thrown. Once a bean instance is removed, any attempt to invoke a method on that instance causes the java.rmi.NoSuchObjectException to be thrown. A container can implicitly call a remove method on an instance after the lifetime of the EJB object has expired. The lifetime of a session EJB object is set in the deployment descriptor with the timeout attribute.

3.2 Developing Session Beans


In their basic make up, session beans are similar to entity beans. However, the purpose of these two types of enterprise beans is very different. From a component point of view, one of the biggest differences between the two types of enterprise beans is that session beans do not have a primary key class. Session enterprise beans do not require primary keys because session EJB objects are created, associated with a specific client, and then removed as needed, whereas entity EJB objects represent permanent data in a data storage are that can be uniquely identified with a primary key. Because the data for session beans is never permanently stored, the session bean class does not have methods for storing data to and loading data from a data source. Every session bean must contain the following basic parts:
u The enterprise bean class. For more information, see Writing the

Enterprise Bean Class on page 23.


u The enterprise beans home interface. For more information, see Writing

the Home Interface on page 31.


u The enterprise beans remote interface. For more information, see

Writing the Remote Interface on page 32.

Writing the Enterprise Bean Class


A session bean class defines and implements the business methods of the enterprise bean, and implements the methods used by the container:
u during the creation of enterprise bean instances u to inform the enterprise bean instance of significant events in the

instances life cycle.

Developing a Session bean

23

By convention, the enterprise bean class is named NameBean, where Name is the name you assign to the enterprise bean. The enterprise bean class for the example Transfer enterprise bean is named TransferBean. Every session bean class must meet the following requirements:
u It must be public, it must not be abstract, and it must implement the

javax.ejb.SessionBean interface. For more information, Implementing the SessionBean interface on page 29.

see

u It must define and implement the business methods that execute the

tasks associated with the enterprise bean. For more information, see Implementing the business methods on page 25.
u It must define and implement an ejbCreate method for each way in which

you want it to be able to instantiate the enterprise bean class. For more information, see Implementing the ejbCreate methods on page 27. Stateful session beans may need to synchronize their conversational state with the transactional context in which they operate. For example, a stateful session bean may need to reset the value of some of its variables if a transaction is rolled back or it may need to change these variables if a transaction successfully completes. If a bean needs to synchronize its conversational state with the transactional context, the bean class must implement the javax.ejb.SessionSynchronization interface. This interface contains methods to notify the session bean when a transaction begins, when it is about to complete, and when it has completed. The enterprise bean developer can use these methods to synchronize the state of the session enterprise bean instance with ongoing transactions. Note: The enterprise bean class can implement the enterprise beans remote interface, but this is not recommended. If the enterprise bean class implements the remote interface, it is possible to inadvertently pass the this variable as a method argument. Figure 4 shows main parts of the enterprise bean class for the example Transfer bean. The sections that follow discuss these parts in greater detail. A session bean can be either stateful or stateless. In a stateless session bean, none of the methods depend on the values of variables set by any other method, except for the ejbCreate method that sets the initial (identical) state of each bean instance. In a stateful enterprise bean, one or more methods depend on the values of variables set by some other method. The Transfer bean is stateless. If the Transfer beans transferFunds method was dependent on the value of the balance variable returned by the getBalance method, the TransferBean would be stateful.

24

Developing Enterprise JavaBeans with VisualAge for Java

import java.rmi.RemoteException; import java.util.Properties; import javax.ejb.*; import java.lang.*; import javax.naming.*; import com.ibm.ejs.doc.account.*; public class TransferBean implements SessionBean { private SessionContext mySessionCtx = null; private InitialContext initialContext = null; private AccountHome accountHome = null; private Account fromAccount = null; private Account toAccount = null; ... public void ejbActivate() throws RemoteException { } ... public void ejbCreate() throws RemoteException { ... } ... public void ejbPassivate() throws RemoteException { } ... public void ejbRemove() throws RemoteException { } ... public float getBalance(long acctId) throws FinderException, RemoteException { ... } ... public void setSessionContext(javax.ejb.SessionContext ctx) throws java.rmi.RemoteException { ... } ... public void transferFunds(long fromAcctId, long toAcctId, float amount) throws java.rmi.RemoteException { ... } } Figure 4. The TransferBean class

Implementing the business methods


The business methods of a session bean class define the ways in which the data encapsulated in instances of the enterprise bean can be manipulated.

Developing a Session bean

25

The business methods implemented in the enterprise bean class cannot be directly invoked by a client. Instead, the client invokes the corresponding methods defined in the enterprise beans remote interface, by using an EJB object associated with an instance of the enterprise bean, and the container invokes the corresponding methods in the enterprise bean instance. Therefore, for every business method implemented in the enterprise bean class, a corresponding method must be defined in the enterprise beans remote interface. The enterprise beans remote interface is implemented by the container in the EJB object class when the enterprise bean is deployed. Figure 5 shows the business methods for the TransferBean class. The getBalance method is used to get the balance for an account. It first locates the appropriate Account EJB object and then calls that objects getBalance method. The transferFunds method is used to transfer a specified amount between two accounts (encapsulated in two Account entity EJB objects). After locating the appropriate Account EJB objects by using the findByPrimaryKey method, the transferFunds method calls the add method on one account and the subtract method on the other. Like all finder methods, findByPrimaryKey can throw both the FinderException and RemoteException exceptions. The try/catch blocks are set up around invocations of the findByPrimaryKey method to handle the entry of invalid account IDs by users. If the session bean user enters an invalid account ID, the findByPrimaryKey method cannot locate an EJB object, and the finder method throws the FinderException exception. This exception is caught and converted into a new RemoteException exception containing information on the invalid account ID. Obtaining the EJB home object is discussed in Implementing the ejbCreate methods on page 27.

26

Developing Enterprise JavaBeans with VisualAge for Java

public class TransferBean implements SessionBean { ... private Account fromAccount = null; private Account toAccount = null; ... public float getBalance(long acctId) throws FinderException, RemoteException { AccountKey key = new AccountKey(acctId); try{ fromAccount = accountHome.findByPrimaryKey(key); } catch(FinderException ex) { throw new FinderException("Account " + acctId + " does not exist."); } return fromAccount.getBalance(); } ... public void transferFunds(long fromAcctId, long toAcctId, float amount) throws RemoteException, InsufficientFundsException, FinderException { AccountKey fromKey = new AccountKey(fromAcctId); AccountKey toKey = new AccountKey(toAcctId); try { fromAccount = accountHome.findByPrimaryKey(fromKey); } catch(FinderException ex) { throw new FinderException("Account " + fromAcctId + " does not exist."); } try { toAccount = accountHome.findByPrimaryKey(toKey); } catch(FinderException ex) { throw new FinderException("Account " + toAcctId + " does not exist."); } try { toAccount.add(amount); fromAccount.subtract(amount); } catch(InsufficientFundsException ex) { throw new InsufficientFundsException("Insufficient funds in " + fromAcctId); } } } Figure 5. The business methods of the TransferBean class

Implementing the ejbCreate methods


You must define and implement an ejbCreate method for each way in which you want an enterprise bean to be instantiated. A stateless session bean must have only one ejbCreate method, which must return void and contain

Developing a Session bean

27

no arguments; a stateful session bean can have multiple ejbCreate methods. Each ejbCreate method must correspond to a create method in the enterprise beans home interface. (Note that there is no ejbPostCreate method in a session bean as there is in an entity bean.) Like the business methods of the enterprise bean class, the ejbCreate methods cannot be invoked directly by the client. Instead, the client invokes the create method in the bean instances home interface, and the container invokes the ejbCreate method. If an ejbCreate method is executed successfully, an EJB object is created. Each ejbCreate method must meet the following requirements:
u It must return void. u It must contain code to set the values of any variables needed by the EJB

object. Figure 6 shows the ejbCreate method required by the TransferBean class. When a container invokes this method, the static method getInitialContext is called to set the enterprise beans initialContext variable. Next, a JNDI lookup is performed by calling the initialContext objects lookup method and passing the name of the Account enterprise bean in string form. The lookup yields a temporary object of type java.lang.Object, which is passed to the static method narrow contained in the Account enterprise beans AccountHomeHelper class to get the AccountHome EJB object. (The AccountHomeHelper class is one of the helper classes generated when the Account enterprise bean is deployed.)

28

Developing Enterprise JavaBeans with VisualAge for Java

public class TransferBean implements SessionBean { private javax.ejb.SessionContext mySessionCtx = null; private InitialContext initialContext = null; private AccountHome accountHome = null; ... public void ejbCreate() throws RemoteException { // Get the initial context try { Properties properties = new Properties(); ... properties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.ibm.jndi.CosNaming.CNInitialContextFactory"); initialContext = new InitialContext(properties); } catch(Exception ex) { ... } ... // Lookup the home interface using the JNDI name try { java.lang.Object o = initialContext.lookup("Account); // this is the JNDI name if (o instanceof org.ong.CORBA.Object) { accountHome = AccountHomeHelper.narrow((org.omg.CORBA.Object) o); } else { // Unexpected object type ... } } catch (Exception e) { // Error getting the home interface ... } } ... }

Figure 6. The ejbCreate method of the TransferBean class

Implementing the SessionBean interface


Every session bean class must implement the methods inherited from the javax.ejb.SessionBean interface. The container invokes these methods to inform the enterprise bean instance of significant events in the instances life cycle. All of these methods must be public, return void, and throw the java.rmi.RemoteException exception.

Developing a Session bean

29

u ejbActivate

This method is invoked by the container when the container selects an enterprise bean instance from the instance pool and assigns it a specific existing EJB object. This method must contain any code that you want to execute when the enterprise bean instance is activated.
u ejbPassivate

This method is invoked by the container when the container disassociates an enterprise bean instance from its EJB object and places the enterprise bean instance in the instance pool. This method must contain any code that you want to execute when the enterprise bean instance is passivated (deactivated).
u ejbRemove

This method is invoked by the container when a client invokes the remove method inherited by the enterprise beans home interface (from the javax.ejb.EJBHome interface). This method must contain any code that you want to execute when an enterprise bean instance is removed from the container.
u setSessionContext

This method is invoked by the container to pass a reference to the javax.ejb.SessionContext interface to a session bean instance. If an enterprise bean instance needs to use this context at any time during its life cycle, the enterprise bean class must contain an instance variable to store this value. This method must contain any code required to store a reference to the context. As shown in Figure 7, except for the setSessionContext method, all of these methods in the TransferBean class are empty because no additional action is required by the bean for the particular life cycle states associated with the these methods. The setSessionContext method is used in a conventional way to set the value of the mySessionCtx.

30

Developing Enterprise JavaBeans with VisualAge for Java

public class TransferBean implements SessionBean { private SessionContext mySessionCtx = null; ... public void ejbActivate() throws RemoteException { } ... public void ejbPassivate() throws RemoteException { } ... public void ejbRemove() throws RemoteException { } ... public void setSessionContext(.SessionContext ctx) throws RemoteException { mySessionCtx = ctx; } ... } Figure 7. Implementing the SessionBean interface in the TransferBean class

Writing the Home Interface


A session beans home interface defines the methods used by clients to create and remove instances of the enterprise bean and obtain meta data about an instance. The home interface is defined by the enterprise bean developer and implemented in the EJB home class created by the container during enterprise bean deployment. The container makes the home interface accessible to clients through the Java Naming and Directory Interface (JNDI). By convention, the home interface is named NameHome, where Name is the name you assign to the enterprise bean. For example, the Transfer enterprise beans home interface is named TransferHome. Every session beans home interface must meet the following requirements:
u It must extend the javax.ejb.EJBHome interface. The home interface

inherits several methods from the javax.ejb.EJBHome interface.


u Each method in the interface must be a create method, that corresponds

to a ejbCreate method in the enterprise bean class. Unlike entity beans, the home interface of a session bean contains no finder methods.
u The parameters and return value of each method defined in the interface

must be valid for Java RMI. In addition, each methods throws clause must include the java.rmi.RemoteException exception class.

Developing a Session bean

31

Figure 8 shows the relevant parts of the definition of the home interface (TransferHome) for the example Transfer bean. This interface defines one create method.

import javax.ejb.*; import java.rmi.*; public interface TransferHome extends EJBHome{ Transfer create() throws CreateException, RemoteException; }

Figure 8. The TransferHome home interface

A create method is used by a client to create an enterprise bean instance. A stateful session bean can contain multiple create methods; however, a stateless session bean can contain only one create method with no arguments. This restriction on stateless session beans ensures that every stateless session bean instances is the same as every other instance of the same type. (For example, every Transfer bean instance is the same as every other Transfer bean instance.) Each create method must be named create and it must have the same number and types of arguments as a corresponding ejbCreate method in the EJB object class. The return types of the create method and its corresponding ejbCreate method are always different. Each create method must meet the following requirements:
u It must return the type of the enterprise beans remote interface. For

example, the return type for the create method in the TransferHome interface is Transfer.
u It must have a throws clause that includes the java.rmi.RemoteException

exception, the javax.ejb.CreateException exception class, and all of the exceptions defined in the throws clause of the corresponding ejbCreate method.

Writing the Remote Interface


A session beans remote interface provides access to the business methods available in the enterprise bean class. It also provides methods to remove an enterprise bean instance and to obtain the enterprise beans home interface and handle. The remote interface is defined by the enterprise bean developer

32

Developing Enterprise JavaBeans with VisualAge for Java

and implemented in the EJB object class created by the container during enterprise bean deployment. By convention, the remote interface is named Name, where Name is the name you assign to the enterprise bean. For example, the Transfer enterprise beans remote interface is named Transfer. Every remote interface must meet the following requirements:
u It must extend the javax.ejb.EJBObject interface. The remote interface

inherits several methods from the EJBObject interface.


u You must define a corresponding business method for every business

method implemented in the enterprise bean class.


u The parameters and return value of each method defined in the interface

must be valid for Java RMI.


u Each methods throws clause must include the java.rmi.RemoteException

exception class. Figure 9 shows the relevant parts of the definition of the remote interface (Transfer) for the example Transfer bean. This interface defines the methods for transferring funds between two Account bean instances and for getting the balance of an Account bean instance.

import javax.ejb.*; import java.rmi.*; import com.ibm.ejs.doc.account.*; public interface Transfer extends EJBObject { ... float getBalance(long acctId) throws FinderException, RemoteException; ... void transferFunds(long fromAcctId, long toAcctId, float amount) throws InsufficientFundsException, RemoteException;} Figure 9. The Transfer remote interface

By stepping through the different tasks required to develop an Enterprise JavaBeans, you have probably realized that a lot of code can be generated for you. VisualAge for Java does it for you and a lot more. This is what we are going to describe in the rest of this book.

Developing a Session bean

33

3.3 Developing Session Bean inside VisualAge for Java


Before starting to develop a session bean we need to describe VisualAge for Java EJB development environment. The EJB Development Environment consists of multiple tools that can be categorized into the following groups: Tools for creating EJBs Tools for generating deployed code for a WebSphere EJS Tools for testing EJBs before you install them into EJSs All of the EJB Development Environment tools are accessible from the EJBs page of the Workbench. The EJBs page is the heart of the EJB Development Environment. This is where your EJB groups and individual EJBs reside, and it is where you accomplish almost all of your EJB development activities. The EJB Development Environment provides all of the necessary run-time support for the IBM WebSphere Application Server. It also leverages the built-in team and versioning capabilities of VisualAge for Java to help you maintain both your EJB source code and generated code.

Creating EJBs
The EJB Development Environment provides tools to help you create EJBs that can be deployed in a WebSphere EJS or in EJB containers provided by other vendors. These tools allow you to accomplish core development activities in the EJBs page,such as creating EJB groups and EJBs. They also allow you to accomplish other development activities, such as writing and editing business logic, importing or exporting EJBs, and managing EJBs. A tool is also provided to help you map entity EJBs to back-end data stores, such as relational databases. There are also tools to help you set deployment descriptor and control descriptor properties prior to running the tools used to generate the deployed code.

34

Developing Enterprise JavaBeans with VisualAge for Java

Figure 10. VisualAge for Java main window

In this chapter we create a stateless session bean called ReadCustomerInfo. It has the responsibility to read data from a serialized file and give as output a CustomerObject initialized with the data contained in the .ser file. The "customer.ser" file must exist in your environment and in order to have flexibility to change its location we set it using the environment property in the deployment descriptor as explained in Generate deployment code inside VisualAge for Java on page 64. The "customer.ser" file is already provided in the CdRom\Part1Samples\SessionBean directory of the CDROM provided with this book.

First step: adding EJB Groups


In a typical VisualAge for Java environment you need to create a project in order to organize your work. Once you have decided what project you need for your EJB development work, you can add EJB groups to the EJBs page to hold your EJBs.

Developing a Session bean

35

An EJB group is a logical group that allows you to organize your EJBs. You can perform global operations on an EJB group that iterate on all of the EJBs that reside in the group. For example, if you select an EJB group to export to an EJB jar file, all of the EJBs contained in the group are exported. Generally when you work with EJBs you need to perform the following three main actions: 1. In the Workbench Projects page create a project 2. In the EJB page create an EJB group. When doing this you are asked to specify the package name. If it does not exist it is created for you and put in the project specified in step 1 3. Create EJBs inside the group specified in step 2. There are two ways to add an EJB group to the EJBs page: Create a new EJB group. Retrieve one or more existing EJB groups from the repository. To add EJB groups: 1. In the Workbench Projects page, from the menu, select Selected->Add Project. The Add Project SmartGuide appears. 2. In the Create a new project named field, type ITSO Bank. This is the name assigned to the new project that will contain your EJBs, then click Finish. The new project appears in the projects page. When creating projects, we suggest that you create a project to hold the EJBs and their related classes, and another project to hold the client application code that will access the EJBs. This helps to keep your code organized. We havent done this for our small session bean sample because there are really few classes to manage. 3. In the Workbench Projects page, click on the EJBs tab. The EJBs page appears.

36

Developing Enterprise JavaBeans with VisualAge for Java

Figure 11. EJB Page

4. From the EJBs menu select Add-EJB Group. The Add EJB Group SmartGuide appears. 5. Beside the Project field, click the Browse button and look for the ITSO Bank the project that we want to contain the EJB group, then click OK. 6. You can do one of the following: Add an EJB group by creating a new group. Add one or more EJB groups by retrieving existing EJB groups from the repository. For our sample purpose we now create a new group. To add an EJB group by creating a new group, ensure that the Create a new EJB group named radio button is selected, and type ITSOEJBGroup which is the name we want to assign to the new group. Your window should now appear like Figure 12

Developing a Session bean

37

Figure 12. Adding a new EJB Group

7. Click Finish. The EJB group is added to the EJBs pane.

38

Developing Enterprise JavaBeans with VisualAge for Java

Figure 13. EJB Page After the Creation of the New Group

Second step: adding EJB to EJB Groups


Once you have added your new EJB group to the EJBs page, you can add EJBs to the EJB groups in one of the following ways: Creating new EJBs Retrieving existing EJBs from the repository Importing EJBs from EJB jar files

This topic discusses how to add EJBs by creating new EJBs. Information about retrieving existing EJBs from the repository and adding EJBs by importing them from a jar file is found in the Appendix A.1, Importing EJBs from a Jar File on page 345. To add EJBs:

Developing a Session bean

39

1. In the EJBs pane, select an EJB group to contain your EJB and click mouse button 2. 2. From the pop-up menu, select Add-EJB. The Create EJB SmartGuide appears.

Figure 14. Create EJB SmartGuide

Using the Create EJB SmartGuide, you can add an EJB by either creating a new EJB or by retrieving one or more existing EJBs from the Repository. Lets see how to add an EJB by creating a new EJB: 1. Ensure that the Create a new EJB radio button is selected.

40

Developing Enterprise JavaBeans with VisualAge for Java

2. In the Bean name field, type in ReadCustomerInfo which is the name that you want to assign to the your new EJB. 3. Since you are creating a new EJB bean class, you need to specify the type of EJB you want to create: session bean, entity bean with bean-managed persistence fields (BMP), or entity bean with container-managed persistence (CMP) fields. The ReadCustomerInfo is a Session Bean so from Bean type drop-down list choose Session Bean. 4. In the Project field, type the project name, modify the default name, or click the Browse button and select the project that contains (or will contain) the EJB bean class from the list of projects, then click OK. By default, the project to which the EJB group belongs is displayed. In our case the project is ITSO Bank. 5. In the Package field, type the project name, modify the default name, or click the Browse button and select the package that contains (or will contain) the EJB bean class, then click OK. If you enter a package that does not exist, a new package is created. type itso.samples.ejb.sessionbean in the package field. 6. In the Class field, either accept the default value or type in a name for the new class. We recommend that you use the default value so that all the implementation types of the EJB are named properly 7. Since we do not provide any superclass for our ReadCustomerInfo bean we do not fill the Superclass field. Before clicking the Next button your EJB Create SmartGuide should look like in Figure 15.

Developing a Session bean

41

Figure 15. Create ReadCustomerInfo EJB

8. After clicking on Next, you are presented with the Define EJB Class Attributes and Interfaces panel (see Figure 16).

42

Developing Enterprise JavaBeans with VisualAge for Java

Figure 16. Adding Import Statements

9. A default EJB Home Interface and EJB Remote Interface names are automatically generated. You can change them or keep the default values. The EJB Key Class is not accessible because session bean do not need a key.

Developing a Session bean

43

10.In the Add import statements to the Bean class, click on Add Package button. 11. This opens a new window where you can select packages and add them by clicking Add button. 12.Repeat the previous step for each package. Once all packages have been added, you can close the window by clicking on Close. The list of added packages appears now in the Add import statements to the Bean class. 13.You can follow the same process to add Interfaces that your bean implements. You dont need to add javax.ejb.Session. The generated code automatically implements this interface because the tool knows we are creating a session bean. 14.Click on Finish at this point. You do not need to go the next page in the SmartGuide because we use the default names the EJB home interface, remote interface. Now you EJB workspace page should look like this:

44

Developing Enterprise JavaBeans with VisualAge for Java

Figure 17. EJB Workspace after the Creation of the New EJB

As you can see in Figure 17 if you select the ITSOEJBGroup the Types pane is populated with three classes: ReadCustomerInfo(remote interface of the ReadCustomerInfo EJB) ReadCustomerInfoBean(bean class of the ReadCustomerInfo EJB) ReadCutomerInfoHome(home interface of the ReadCustomerInfo EJB) If you go back to Developing Session Beans on page 23 you can see what is needed in order to create and EJB and how much easier is to create it using VisualAge for Java. In fact VisualAge for Java automatically generates the three classes required for creating an EJB following the specification rules. You can have a look of what is generated inside each of this class by simply selecting it in the Types pane and look the displayed methods in the Methods pane. As you can see the remote interface is empty. It is up to you to decide

Developing a Session bean

45

which are the method you need to put in the Remote interface ReadCustomerInfo. The Home interface instead shows the create() method that our session bean at least must have. Remember since the ReadCustomer session bean is a stateless session bean we do not implement any additional create() method. You can add new methods to your bean class and make them appear in the Home or Remote interface. In order to do this you never manipulate the source code of these two interfaces directly. Detailed explanation on how to do this is found in Adding methods to EJBs on page 49 The ReadCustomerInfo is a simple stateless session bean that access a serialized file in order to read simple customer information. For this reason you need to do some additional steps before you can start developing your session bean. In CdRom\Part1Samples\SessionBean directory of the CDROM we provide the following CustomerObject.jar file. It contains a CustomerObject serialized JavaBeans to be used by the CustomerInfo sessionbean. Import it into your ITSO Bank project. An itso.samples.ejb.sessionbean.model package should now show up in the ITSO Bank project. Now we can proceed building our ReadCustomerInfo session bean. Go back to the EJB workspace. We need to create new fields to the ReadCustomerInfo session bean. Since this is a stateless Session Bean the field are private attribute for the bean.

Adding Fields to EJBs


When you create an EJB in the EJB Development Environment, certain fields are created automatically in the bean class. In the case of a session bean the javax.ejb.SessionContext mySessionCtx is created. This topic explains how to add three more fields to the EJB after it has been created. We need to define the following fields:
private String fileName = null; private FileInputStream fInput; private ObjectInputStream input;

You can display EJB fields by selecting the EJB in the EJBs pane, and then selecting the Fields icon in the upper right corner of the Types pane to toggle to the Fields pane. The Fields pane and the Types pane share the same space on the EJBs page and can be displayed alternately by selecting the icon in the upper right corner of the pane. To display the Types pane, select the Types icon .

46

Developing Enterprise JavaBeans with VisualAge for Java

The reason why we declared all the fields as private is because our session bean is stateless. If you want to make it a stateful session bean you have to declare all the fields as public so that the container takes care of their state during passivation. To add a field to the bean class: 1. In the Types pane of the EJBs page, select the EJB bean class to which you want to add a field. 2. Click mouse button 2, then select Add Field from the pop-up menu. The Create Field smartguide appears.

Figure 18. Create Field smartguide

3. In Field Name, enter fileName 4. Select String in the Field Type combo box.

Developing a Session bean

47

5. Type null in the Initial Value field. 6. Select private as Access Modifier. Our bean is stateless this is why we declare private fields. If the bean had been declared Stateful, then we should have declared the fields as public. 7. Check the Access with getter and setter methods checkbox so getters an setters methods are generated by the tool for you. This is how the smart guide should look like now:

Figure 19. Create fileName Field

8. Click Finish.

48

Developing Enterprise JavaBeans with VisualAge for Java

You need to repeat the above steps to create the fields:


u fInput of type FileInputStream and u input of type ObjectInputStream

Since we all make mistakes, we may have created a field that we really dont need. The question is how do we delete fields?

Deleting Fields to EJBs


There is no automatic way to delete a field from an EJB all the operation should be done manually. What you need to do is the following: 1. In the Types pane of the EJBs page, select the EJB bean class from which you want to delete a field. 2. From the Methods pane select the corresponding setter and getter method (use Ctrl key for multiple selection). Click mouse button 2, then select Delete 3. In the Types pane of the EJBs page, select the EJB bean again and delete the field instance manually from the source code. In this version of VisualAge for Java, selecting a field and delete is not yet provided. After the creation of all necessary fields, we carry on by adding new methods to the session bean. We need to add three new methods. The openFile() and closeFile() methods are needed only for accessing the serialized file customer.ser. The readCustomer() instead is used to read the information from the serialized file and return them into a CustomerObject. Modifying methods or adding methods in the EJB Development Environment is similar to modifying or adding methods elsewhere in VisualAge for Java.

Adding methods to EJBs


To add a new method do the following: 1. In the Types pane of the EJBs page, select the EJB bean class to which you want to add a method. Select ReadCustomerInfoBean 2. Click mouse button 2, then select Add Method from the pop-up menu. The Create Method SmartGuide appears.

Developing a Session bean

49

Figure 20. Create Method smartguide

3. Select Create a new method radio button. 4. Type CustomerObject readCustomer() as shown in Figure 21.

50

Developing Enterprise JavaBeans with VisualAge for Java

Figure 21. Create Method SmartGuide - First Page

5. Click Next to go to the next page. 6. Select public as the Access Modifiers and since the readCustomer method can throw an IOException you need to add this exception in the What exception may this method throws? list. In order to do this click the Add button and type the exception name. When you are finished click Close (see Figure 22). You need to go on the second page only if you want to change the modifiers attribute or if you want the SmartGuide to handle additional

Developing a Session bean

51

exception. If you are not under this condition you can skip step 5 and step 6.

Figure 22. Create Method SmartGuide - Second Page

7. Click Finish to create the new method You now need to create the other two methods following the same steps. The two methods have the following signature:
public void openFile(); public void closeFile() throws java.io.IOException;

52

Developing Enterprise JavaBeans with VisualAge for Java

Now we need to fill the methods with the right code and understand what do we do with this new business methods. Here is the code to be inserted in each method:
private void closeFile() throws java.io.IOException{ if(input!=null){ input.close(); input=null; } } private void openFile() { try { //Need to initialize the fileName field from what is defined in //the environment fileName=(String)props.get("customerFile"); fInput= new FileInputStream( fileName); input = new ObjectInputStream( fInput); } catch(Exception e){ System.out.println("Error in opening: " + e); } } public CustomerObject readCustomer() throws java.io.IOException{ try{ openFile(); if (fInput.available() > 0){ System.out.println("INIT ---> Reading object"); CustomerObject cO=(CustomerObject)input.readObject(); System.out.println("END ---> Reading object"); closeFile(); return cO; } } catch(Exception e) { e.printStackTrace(System.out); } return null; }

After you create methods, you need to promote to the remote interface those that will be accessed by a client. In our case, only the readCustomerInfo method needs to appear on the remote interface.

Developing a Session bean

53

Adding Methods to the Remote Interface


To promote a method to the remote interface do the following: 1. Select the method and then select Methods-Add-to-EJB Remote Interface. So to promote the readCustomer() method to the remote interface select it and from the Methods menu select Add to - EJB Remote Interface. Another way to do the same thing is select the method, click the mouse button 2 and from the popup menu select Add to - EJB Remote Interface. Once the method has been promoted you can notice a small icon appearing near the method. This icon help you to identify all the methods that have been declared in the remote interface. Since the ReadCustomerInfo bean does not have any further create or finder method we do not need to add any additional method to the home interface. We will see this option later in the book.

Removing Methods from the Remote Interface


After you have added a method to the remote interface you can also remove it. To do this in the EJB bean class select the method and then Methods Remove From - EJB Remote Interface. In this case the method is only removed from the remote interface but still exists in the EJB bean class. If you really want to get rid off the method, delete it from the EJB bean class instead, then the corresponding method in the remote interface is automatically removed.

54

Developing Enterprise JavaBeans with VisualAge for Java

Your workspace should now look like Figure 23

Figure 23. RaedCustomerInfoBean in the EJB Workspace

You have now completed the development steps for the ReadCustomerInfoBean. Let us see how to deploy it and test it inside VisualAge for Java.

Generating Deployed Code


Once an enterprise Bean is developed, the next step is to deploy that Bean into a container. However, before you can deploy an enterprise Bean, you must first create the deployment descriptor, which defines the transaction, security, and other environment specifications that determine how the enterprise Bean is managed by the container.

Developing a Session bean

55

The deployment descriptor


The deployment descriptor contains attribute and environment settings that define how the container invokes enterprise Bean functionality. The content of the deployment descriptor is decided during different phases:
u application analysis u bean development u bean deployment

For example, during analysis you may decide that a bean is going to use a file name that must not be hardcoded. Then, during development phase, the developer decides that the file name is going to be passed to the bean by using a property name. At last, during deployment, the deployer can change the value of the property name with a new value pointing to a different fully qualified path and file name (see Figure 61 on page 104). Every enterprise Bean (both session and entity) must have a deployment descriptor that contains settings for the following attributes; these attributes can be set for the entire enterprise Bean or for the individual methods in the Bean. The container uses the definition of the Bean-level attribute unless a method-level attribute is defined, in which case the latter is used.
u Transaction attribute:Defines the transactional manner in which the

container invokes a method. The values for this attribute are described Chapter 7, Transactions on page 211
u Transaction

isolation level attribute:Defines the degree to which transactions are isolated from each other by the container. users or roles that are permitted to access the methods in the enterprise Bean. The values for this attribute are defined by enterprise Bean deployers and the system administrator.

u Access control attribute:Defines an access control entry that identifies

u RunAsMode and RunAsIdentity attributesThe RunAsMode attribute

defines the identity used to invoke the method. If a specific identity is required, the RunAsIdentity attribute is used to specify that identity. The deployment descriptor for a session Bean must also contain settings for the following attributes. These attributes can be set on the Bean only; they cannot be set on a per-method level.
u State management attribute:defines the conversational state of the

sessionBean. This attribute must be set to either STATEFUL or STATELESS.

56

Developing Enterprise JavaBeans with VisualAge for Java

Timeout attributeDefines the timeout value in seconds associated with this session Bean. This is a value needed for the container. Idle instances of a session Bean are removed by the container after this specified time period has elapsed. Deployment descriptors can be created by using the tools within an integrated development environment (IDE) like IBMs VisualAge for Java or by using the stand-alone tools contained in WebSphere. You provide this information to VisualAge for Java by using a smartguide and later, the tool generates the serialized deployment descriptor for you as well as all the required files that go into the deployable jar file. To launch this smartguide, from the EJB Workspace : 1. Go to the EJBs pane. 2. Select ITSOEJBGroup. 3. Select ReadCustomerInfo bean class. 4. Click mouse button 2, then select Properties. The Properties window appear:

Developing a Session bean

57

Figure 24. Properties Window

In the first page that appear you recognize all values described in the The deployment descriptor on page 56 section. We keep the default values on this first page. If you need to change the Java Naming and Directory Interface ( JNDI) name or control attributes at the bean level, do one or more of the following:
u In the Enter the JNDI name for BeanHome field, type the JNDI

name to associate with the EJB in the JNDI name space. The container will bind the EJB's home interface with a JNDI name that includes the name you specified. The name you specify in this field is the name that your client code pass to the naming context.
u In the Transaction Attribute drop-down box, select a transaction

attribute. This attribute tells the container how to manage transaction scopes before and after the execution of the EJB method.
u In the Isolation Level drop-down box, select an isolation level. This

level tells the container what isolation level to set on the database connections used by the EJB at the start of each transaction.

58

Developing Enterprise JavaBeans with VisualAge for Java

u In the Run-As Mode drop-down box, select a run-as mode. This selection

tells the container the security identity to associate with the execution of the EJB method.
u For session EJBs only, in the State Management Attribute drop-down

box, specify whether or not you want the container to maintain state information for the EJB.
u For session EJBs only, in the Session Timeout Value (seconds) field,

specify after how many seconds a session should timeout. During runtime, our bean needs to know where to get a file called customer.ser which contains a serialized instance of a Customer object. We pass this information through the environment properties. Click the Environment tab. The Environment tab page appears.

Figure 25. Environment Properties Page

You can do one or more of the following:


u To set an environment property, specify the variable name in the

Variables field and its associated value in the Values field, and click Set.

Developing a Session bean

59

u To select an environment property defined for the EJB, click on the

properties in the Environment Properties list, and click OK


u To delete an environment property, select the property you want to delete,

and click Delete. In order to add the property we need, to do the following: 1. In the Variables field type customerFile 2. In the Values field type c:\customer.ser. It indicates where the "customer.ser" is located. We assume the file is located under the root directory. If you copy it somewhere else, ensure that the property is updated. The properties window should now appears like in Figure 26.

Figure 26. Environment Properties Page after Definition of a Property

60

Developing Enterprise JavaBeans with VisualAge for Java

If you want to use Environment properties you need to define a Properties field in the bean class (see Figure 27).

Figure 27. Definition of the Properties Field

This Properties field is initialized in the setSessionContext() method as shown in Figure 28.

Figure 28. Getting Properties from the Context

Now you need to initialize the fileName variable reading the information from the properties. We do it in openFile() (see Figure 29).

Figure 29. Retrieve Environment Variable Value from Properties

We do not need to to change the control attributes at the method level but if you need to do this click the Method tab. The Method page appears:

Developing a Session bean

61

Figure 30. Method properties Window

To add a method-level control descriptor, click Add. The Add Control Descriptor at Method Level dialog appears:

62

Developing Enterprise JavaBeans with VisualAge for Java

Figure 31. Method Selection

If you select a method from the list and click OK, the following dialog appears:

Figure 32. Modify Method Control Descriptor Window

The displayed attribute values are those defined at the bean level. Modification done in this window affect the selected method only.

The ejb-jar file


The ejb-jar file is the file format used to package enterprise Beans; this file uses the standard Java programming language Archive File. The ejb-jar file

Developing a Session bean

63

can be used to contain individual enterprise Beans, multiple enterprise Beans, and entire enterprise Bean-based applications. For an individual enterprise Bean, an ejb-jar file must contain the following files:
u The .class files that make up the Bean u The deployment descriptor u The manifest file that identifies the contents of the jar file.

Manifest files are organized into sections that are separated by blank lines;each section corresponds to a file stored in the .jar file. Each section contains one or more tag-value pairs with the syntax tag:value. The section corresponding to the deployment descriptor file for each enterprise Bean in a .jar file must contain the following headers:
Name: deploymentDescriptorFile Enterprise-Bean: True

The manifest file must be named META-INF/MANIFEST.MF. An ejb-jar file can be created by using the tools within an integrated development environment (IDE) like IBMs VisualAge for Java or by using the stand-alone tools contained in WebSphere.

Deploying an enterprise Bean


When you deploy an enterprise Bean, the deployment tool creates the following elements:
u The container-implemented EJBHome object and EJBObject classes from

the enterprise Beans home and remote interfaces (and the persistor and finder classes for entity enterprise Beans with CMP).
u The Java ORB, stub, and skeleton files required for remote method

invocation (RMI).
u Helper and holder classes for the home and remote interfaces.

An enterprise Bean can be deployed by using the tools within an integrated development environment (IDE) like IBMs VisualAge for Java or by using the stand-alone tools contained in WebSphere. NOTE: If you add a remote method and promote it to the remote interface after generating the deployed code, you must regenerate the deployed code.

Generate deployment code inside VisualAge for Java


We are now ready to generate the deployment code for the Bean:

64

Developing Enterprise JavaBeans with VisualAge for Java

1. In the EJBs pane select ReadCustomerInfo bean class. 2. Click mouse button 2, then select Generate->Deployed Code item from the EJB menu. The Types pane is now populated with the generated classes.

Figure 33. EJB WorkSpace after the EJB Deployment Code Generation

Generate the Test Client


VisualAge for Java contains a complete Enterprise JavaBeans server runtime environment. When you request VisualAge for Java to generate deployed code, it does it for the WebSphere Advanced Edition 2.0 containers. Then you can immediately run your Enterprise JavaBeans, debug and test them inside your IDE. To make developer life even easier, it also generate a so called test client.

Developing a Session bean

65

The test client is generated for each Enterprise JavaBeans. Then you can use it to do unit test. The main purpose of the test client is to interactively test each of the methods in the home and remote interfaces. The test client features a graphical user interface that allows you to select a method from either the home or remote interface and then test the selected method. The test client is generated from the home and remote interfaces and the deployment descriptor of the EJB. For each method defined in the remote interface, a local proxy method is generated into the test client class. You can customize each method by editing the method directly. To generate the EJB test client do the following: 1. Go to the EJBs pane. 2. Select ITSOEJBGroup. 3. Select ReadCustomerInfo bean class. 4. Click mouse button 2, then select Generate-Test Client item from the EJB menu. A default EJB test client class appears in the Types pane of the EJBs page under the following name ReadCustomerInfoTestClient.

66

Developing Enterprise JavaBeans with VisualAge for Java

Figure 34. Generate Test Client

Note: to hide the test client and other generated classes in the Types pane, in the upper right corner of the Types pane, click the Show Generated Types toggle button.

Testing EJBs
To run and test the ReadCustomerInfo session bean you need to create an EJB server configuration in which you can test your EJB. Configuring a server configuration for your EJB consists in adding the EJB group that contains your EJBs to a server configuration. To create an EJB server configuration: 1. From the EJBs page, select ITSOEJBGroup.

Developing a Session bean

67

2. Click mouse button 2, and then select Add to - Server Configuration from the pop-up menu. The EJB Server Configuration browser appears.

Figure 35. EJB Server Configuration

An EJB server entry is added in the Servers pane. The EJB server contains the ITSOEJBGroup. Once you create your EJB server configuration, you may need to set some properties. Even though, in our case, we use default values, let us have a look to the different settings that can be done.

Setting Name Service and EJB Server Properties


The name servers that are used by the EJB Server Configuration browser are configurable. The name servers work with the default values that are configured for them. This topic describes how to change them if so desired. Note that once set, any name server or EJB server properties are saved even if you exit VisualAge for Java.

68

Developing Enterprise JavaBeans with VisualAge for Java

Setting Properties for the Location Service Daemon


To set the properties for the Location Service Daemon: 1. In the EJB Server Configuration browser, in the Servers pane, select the Location Service Daemon. 2. Click mouse button 2 and select Properties from the pop-up menu. The Location Service Daemon properties dialog appears:

Figure 36. Location Service Properties Dialog

3. Type in the port number for the ORB Listener Port. Note that the value for the ORB Listener Port must match the value for the LSD Port in the Persistent Name Server.

Setting Properties for the Persistent Name Server


To set the properties for the Persistent Name Server: 1. In the EJB Server Configuration browser, in the Servers pane, select the Persistent Name Server.

Developing a Session bean

69

2. Click mouse button 2 and select Properties from the pop-up menu. The Persistent Name Server Properties dialog appears.

Figure 37. Persitent Name Service Property Dialog.

3. Modify the default values accordingly. The Initial Root value is a working directory where certain information is written about the persistent data. In the LSD Name field, the Location Service Daemon can run on another machine other than the supplied default of localhost. Note that the LSD Port number must match the ORB Listener Port of the Location Service Daemon.

Setting Properties for the EJB Server


If you just want to test and debug an EJB and associated client application that you are running within VisualAge for Java, you should not need to change the default properties that are automatically established for the EJB server. However, only if you are testing an entity EJB, you must ensure that the database URL references a database that is configured on your system. To set the properties for the EJB server: 1. In the EJB Server Configuration browser, in the Servers pane, select the EJB server. 2. Click mouse button 2 and select Properties from the pop-up menu. The Properties for EJB Server dialog appears.

70

Developing Enterprise JavaBeans with VisualAge for Java

Figure 38. EJB Server Properties Dialog.

3. If you are testing an entity EJB, in the Database URL field, ensure that the URL of a database is specified that is configured on your system. For example: jdbc:db2:MyDatabase 4. If your database is set up so that a user ID and password is required to access the database, then specify a user ID and password in the Database User ID and Database Password fields. 5. If you changed the default port values, ensure that the LSD Port number matches the ORB Listener Port of the Location Service Daemon. Since we are dealing with session bean we do not need to take care about persistence aspects.

Starting the Name Service and EJB Servers


Once you have created an EJB server configuration, you need to start the Location Server Daemon, the Persistent Name Server and your EJB server before you can test your EJB. To start the servers: 1. In the EJBs page, select EJBs - Open To - Server Configuration. The EJB Server Configuration browser appears.

Developing a Session bean

71

2. In the Servers pane, select the Location Service Daemon and click mouse button 2, then select Start Server. 3. In the Servers pane, select the Persistent Name Server and click mouse button 2, then select Start Server. You can also, select a server and from the tool bar, click on . In the same way, you can stop a server by clicking on the icon . The Console window appears in the background and monitors the two servers. 4. In the Console, check that the Location Service Daemon and the Persistent Name Server are listening by selecting each server (one at a time) in the All Programs pane and looking for the following messages in the Standard Out pane:
Location service daemon listening... NameServer is listening...

To start the EJB server: 1. Once the Location Service Daemon and the Persistent Name Server are running, in the Servers pane of the EJB Server Configuration browser, select the EJB server (server1) and click the icon to start the server. The Console window now also monitors the EJB servers.

Figure 39. Console After all Servers are Started.

72

Developing Enterprise JavaBeans with VisualAge for Java

2. In the Console, check that the EJB server is ready to process a call from the client by selecting the EJB server entry at the bottom of the All Programs pane and then looking for the following message in the Standard Out pane:
Server is listening...

3. You can change the source code of any EJB in the EJB server configuration and debug it without stopping the EJB server. However, if you change the home or remote interfaces, you must do the following: 1. Stop the EJB server. (Information about stopping the EJB Server is found in the topic Stopping the Name Service and EJB Servers on page 85.) 2. Regenerate the deployed code. 3. Start the EJB server again. Note: If you create an EJB server configuration that contains a number of EJBs and then you decide that you want to delete one of the EJBs, you should stop the EJB server before deleting the EJB.

Restarting Servers
In some situations, you may want to perform a restart on a server that is already running. Essentially, this resets the running server to the state it was in when it was first started. To restart a server: 1. In the EJBs page, select EJBs - Open To - Server Configuration. The EJB Server Configuration browser appears. 2. In the Servers pane, select the server that you want to restart. 3. Click mouse button 2, and select Restart Server from the pop-up menu. In the Servers pane, an icon appears beside the server to indicate that it is running.

Running the Generated Test Client


Now we are ready to run the test client to test the EJB's home and remote interface methods, and to debug the ReadCustomerInfo EJB implementation. When running the test client, you can set breakpoints in your EJB implementation and use the VisualAge for Java debugger as you would normally do. All of the Java projects found in the workspace are automatically added to the test client classpath if you start the test client from either the EJB Server

Developing a Session bean

73

Configuration browser or the EJBs page. The test client will also automatically locate the EJB using the JNDI name specified as part of the EJBs deployment descriptors. If you start the test client outside of the EJB Server Configuration browser or the EJBs page, you need to set the classpath of the test client program. We recommend that you start the test client in either the EJB Server Configuration browser or in the EJBs page. We now describes the basic steps required to run the test client. To run the default test client: 1. In the EJB Server Configuration browser, ensure that the Name Service servers and the EJB Server are running. (Information about starting these servers is found in the topic, Starting the Name Service and EJB Servers on page 71. 2. In the EJBs pane of the EJB Server Configuration browser, select the ReadCustomerInfo EJB for which you have created a test client. (If the EJB does not appear in the EJBs pane of the EJB Server Configuration browser, you must add the EJB to a server configuration by following the instructions in the topic, Testing EJBs on page 67.

74

Developing Enterprise JavaBeans with VisualAge for Java

3. Click on the Run Test Client icon to run the test client. The Connect page of the Test Client window appears:

Figure 40. Connect Window for the ReadCustomerInfo Session Bean

4. The Provider URL field contains the hostname of the server you are connecting to. In this case iiop:/// stands for iiop://localhost. The JNDI name field contains the JNDI name for your EJB. To find out which is the JNDI name of your EJB please refer to Generate deployment code inside VisualAge for Java on page 64 on how to get to the EJB Properties window ( see Figure 24 on page 58) The Initial Context Factory field contains the class name to be used as the context factory of the naming service. The Home Interface contains the fully qualified name of the EJB Home interface. The Home Helper field contains the fully qualified name of the Helper class of the EJB being tested To establish a connection to the name server, click the Connect button. The client constructs an initial naming context, and ask the name server to look up an instance of the home interface for the ReadCustomerInfo EJB you are testing. Once the connection is made and an instance of the home interface is retrieved, the test client automatically switches to the Home Interface page

Developing a Session bean

75

Figure 41. Home Test Client Page

Figure 41 shows the test client for the ReadCustomerInfo bean. ReadCustomerInfo is a stateless session bean, so its home interface (ReadCustomerInfoHome) contains only one create method. The other methods shown are defined by the javax.ejb.EJBHome interface, which ReadCustomerInfoHome extends, and they are marked with a trailing :: EJBHome. 5. In the Methods pane, select the create() method. Click the Send button in order to create the remote interface object. This sends the method call to the EJB server to create the new ReadCustomerInfo bean. The resulting remote interface object will be used by the test client for testing remote methods When the remote interface object is retrieved, the test client will switch to the Remote Interface page:

76

Developing Enterprise JavaBeans with VisualAge for Java

Figure 42. Remote Test Client Page

In the Remote Interface page, the Methods pane contains the list of methods defined by the remote interface, plus methods defined by the interface javax.ejb.EJBObject. 6. Select the readCustomer() method in the Methods pane. 7. Click the Send button to send the method to the EJB. The result of the method call is displayed below the Methods pane. The result should look as in Figure 43.

Developing a Session bean

77

Figure 43. Testing Remote Methods

8. If you want to examine the result object, click the Inspect button. This launches the VisualAge for Java Inspector.

78

Developing Enterprise JavaBeans with VisualAge for Java

Figure 44. Inspector Window

After testing the ReadCustomerInfo EJB we can now build our own client application.

3.4 Writing Your Own Client Application


We have provided to you the client application. You can find it in the SB client.jar file in the \Part1Samples\SessionBean directory of the CDROM. Import the SB client.jar file into your ITSO BANK project. An enterprise Bean can be accessed by different types of clients: A Java servlet. A Java Server Page (JSP). A Java application. Another enterprise Bean. While this chapter discusses the first two types of Java clients only, all of the programming tasks described in this chapter also apply to enterprise Beans acting as clients to other enterprise Beans. This chapter assumes that you understand how to write a Java servlet and a Java application. To access and 79

Developing a Session bean

use an enterprise Bean in a Java client, the client must contain code that does the following: Imports the Java packages required for naming, remote method invocation,and EJB interaction. Instantiates the Beans EJB object. For more information, see Instantiating an EJB Object on page 80. Refreshes the reference to each EJB object associated with a session Bean if the reference becomes invalid.

Importing required Java packages


While, the Java packages required for any particular enterprise Bean client vary, the following packages are required by all clients:
u java.rmi.* This package contains the classes and methods required for

remote method invocation (RMI).


u java.util.* This package contains various Java utility classes, such as

Properties, Hashtable, and Enumeration used is a variety of ways throughout all enterprise beans.
u javax.ejb.* u javax.naming.* u The package for each enterprise Bean with which the client interacts.

Instantiating an EJB Object


To invoke a Beans business methods, a client must create or find an EJB object for that Bean. Once the client has created this object, it can invoke methods on it in the standard way. To create or find an instance or a Beans EJBObject, the client must instantiate the EJBHome object for that Bean. The EJBHome object, can then be used to create or find (for entity Beans only) an instance of the Beans EJBObject. The ReadCustomerInfo client application is a simple application that shows the data read from the .ser file in a window:

80

Developing Enterprise JavaBeans with VisualAge for Java

Figure 45. Read Customer Client Window

The ReadCustomerInfo client application is made of two JavaBeans the ReadCustomerClient and the ViewController. It follows the MVC paradigm The ReadCustomerClient is the visual part and the ViewController is the controller on the visual part. This means that all the access to the EJB and the action performed on the button goes really to the controller, The model is represented by the ReadCustomerInfo EJB. The ViewController has a create(String,String,String ) method that is called inside the getCustomer() method of the ViewController class. The parameter passed here respectively the hostname,the naming service class to be used,and the port number. When the windowOpened event is detected for the ReadCustomerClient an instance of ViewController is created with the right parameters. The code in this section is taken from the example Java application ViewController.java; all of this code is contained in the applications create(String,String,String) method. The Enterprise JavaBeans specification contains instructions for using classes in the javax.rmi package to locate a Beans home interface. Unfortunately, this package has not been implemented. Therefore, IBM has implemented an alternative way to locate a home interface by using the IBM CosNaming naming and directory service. Locating an enterprise Beans home interface is a two-step process. First, you create a javax.naming.InitialContext object. Then, you use the InitialContext object to get the EJBHome object.

Developing a Session bean

81

The code below shows what is required to create the InitialContext object. To create this object, you construct a java.util.Properties object, assign environment values to the Properties object, and then pass the object as the argument to the InitialContext constructor.
public void create(String host,String port) { ReadCustomerInfoHome rCHome = null; javax.naming.InitialContext initContext = null; // Get the initial context try { System.out.println("Retrieving initial context..."); java.util.Properties properties = new java.util.Properties(); // local name server System.out.println("-------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://"+host+":"+port); properties.put(javax.naming.Context.PROVIDER_URL, "iiop://"+host+":"+port); // IBM name services System.out.println("-------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory"); properties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, com.ibm.jndi.CosNaming.CNInitialContextFactory"); System.out.println("-------Invoke: javax.naming.InitialContext(properties)"); initContext = new javax.naming.InitialContext(properties); } catch (javax.naming.NamingException e) { System.out.println("Error retrieving the initial context: " + e.getMessage()); System.exit(0); } // endtry catch (Exception e1) { System.out.println("Error retrieving the initial context: " + e1.getMessage()); e1.printStackTrace(System.out); System.exit(0); } // lookup the home interface using the JNDI name ........ // create a new ReadCustomerInfo to set ...... set... }

Once the InitialContext object is created, the application uses it to create the EJBHome object. This creation is accomplished by invoking the lookup method which takes the Java Naming and Directory Interface (JNDI) name

82

Developing Enterprise JavaBeans with VisualAge for Java

of the enterprise Bean in String form and returns a java.lang.Object object. The returned object is filtered, using the static method narrow, to obtain an EJBHome object for the specified enterprise Bean. The narrow method is contained in the home helper class generated during Bean deployment. For the ReadCustomerInfo Bean, this home helper class is named ReadCustomerInfoHomeHelper.
public void create(String host,String port) { ReadCustomerInfoHome rCHome = null; javax.naming.InitialContext initContext = null; ..... //Get the Initial context ..... // lookup the home interface using the JNDI name try { System.out.println("Retrieving the home interface..."); java.lang.Object o = initContext.lookup("ReadCustomerInfo"); // this is the JNDI name if (o instanceof org.omg.CORBA.Object) rCHome = ReadCustomerInfoHomeHelper.narrow((org.omg.CORBA.Object) o); } catch (javax.naming.NamingException e) { System.out.println("Error retrieving the home interface: " + e.getMessage()); System.exit(0); } // endtry ... // Create a new ReadCustomerInfo to set ... set.. }

The code below shows how to create the EJB object by using the EJBHome object. The EJB object is obtained by calling a create method.
public void create(String host,String port) { ReadCustomerInfoHome rCHome = null; javax.naming.InitialContext initContext = null; ..... //Get the Initial context ..... // lookup the home interface using the JNDI name // Create a new ReadCustomerInfo to set System.out.println("Creating new ReadCustomerInfo..."); ReadCustomerInfo rC = null;

Developing a Session bean

83

try { rC = rCHome.create(); System.out.println("ReadCustomerInfo created!"); } catch (Exception e) { System.out.println("Exception creating new ReadCustomerInfo: " + e.getMessage()); e.printStackTrace(System.out); System.exit(0); } // endtry if(rC== null) System.out.println("Unable to creating ReadCustomerInfo "); //this method sets the ReadCustomerInfo instance in the ViewController class setReadCustomers(rC) }

You can open the ReadCustomerClient to the visual composition editor in order to understand the application flow. To start and test the ReadCustomerClient client inside VisualAge: 1. In the EJB Server Configuration browser, ensure that the Name Service servers and the EJB server are running. 2. In the EJBs pane of the EJB Server Configuration browser, select the EJB which you will access with your own client application. 3. In the Workbench Projects page or other page where your client resides, select your client class and click mouse button 2, then select Properties. The Properties dialog appears. 4. In the command line argument type hostname 9001 as parameters 5. Click the Class Path tab. 6. Beside the Project Path field, click the Edit button. The Class Path dialog appears. 7. Select the IBM WebSphere Test Environment project and click OK. 8. At the bottom of the Properties dialog, select the Save in repository (as default) check box and click OK. 9. Select your client class, then click mouse button 2 and select Run - Run main. 10.When the ReadCustomerClient window appear click the Get Customer Data button. The result should be as in Figure 45
1

In the VisualAge for Java IDE, the Persistent Name Server runs on port number 900.

84

Developing Enterprise JavaBeans with VisualAge for Java

Once you finished to test your EJB you need to sop the servers. (I put this in the appendix if it s ok we need to remove it from here and refer to the appendix)!!!!!!!

Stopping the Name Service and EJB Servers


To stop a server: 1. In the EJB Server Configuration browser, in the Servers pane, select the server and 2. Click on the icon to stop the server.

The Console window indicates that the server has been terminated. Removing EJB Servers You cannot remove the Location Service Daemon or the Persistent Name Server. You may, however, remove EJB servers from the EJB Server Configuration browser. To remove an EJB server: 1. In the EJB Server Configuration browser, in the Servers pane, select the EJB server that you want to remove. 2. Click on the icon to stop the server (if it is not already stopped). 3. Select the EJB server again, click mouse button 2, and select Remove Server from the menu. The EJB server is removed from the list of servers in the Servers pane.

3.5 Running the client outside VisualAge for Java


Exporting EJB Groups and EJBs
Before staring to go in the details of the how to deploy a client application outside VisualAge for Java we need o give you some general information on how to export EJBs from VisualAge for Java.

Exporting EJBs to EJS or EJB Jar Files


Once you have tested your EJBs, you can export them to an EJS jar file, EJB jar file, or client jar file. (Information about exporting to a client jar file is found in the topic Exporting EJBs to Client Jar files on page 88.)

Developing a Session bean

85

An EJS jar file contains both EJB code and deployed classes. An EJB jar file contains EJB code, but no deployed classes. NOTE: All the EJS runtime files are excluded automatically from the jar file. To export an EJB to an EJS or EJB jar file: 1. In the EJBs pane of the EJBs page, select one or more EJB groups or EJBs. 2. Click mouse button 2, then do one of the following:

Figure 46. Exporting .jar Files

To export EJB code and deployed classes, select Export - EJS JAR from the pop-up menu. After the jar file is created, you can install it on a WebSphere EJS.

86

Developing Enterprise JavaBeans with VisualAge for Java

To export EJB code select Export - EJB JAR from the pop-up menu. After the jar file is created, you can deploy it into a EJB container using the deployment tool provided by the EJB Container provider. If you choose the Export to an EJB Jar File SmartGuide appears.

Figure 47. Export to an EJB jar File

3. In the Jar file field, type the name of the jar file you want to create. Alternatively, click the Browse button to select an existing jar file to

Developing a Session bean

87

overwrite. The SmartGuide marks all of the class files associated with the selected EJB groups or individual EJBs for exportation to the jar file. 4. To select individual file types to export, click one or more of the following check boxes: beans: export all the beans in the EJB group or the individual EJB you selected. class files: export all the bytecode files for the selected EJB group or EJB. java files: export all the source code files for the selected EJB group or EJB. resource: export all the non-.java and non-.class files for the selected EJB group or EJB. Details: by default, all the files for the selected file type are exported. Click the Details button next to a file type to see a list of the files that will be exported, and to specify individual files to export. 5. To ensure that any types or resources referenced by the selected EJB group or EJB are also exported, click the Select referenced types and resources button. 6. Specify additional options as appropriate using the Options check boxes as follows: Include debug attributes in .class files: if you want to debug the exported classes using an external debugger, click this check box to include debugging information for the exported classes. Compress the contents of the jar file: compress the exported files. Overwrite existing files without warning: if you are exporting to an existing jar file, and you do not want to be warned about overwriting existing files, click this check box. Automatically open a web browser on created .html files? Do not click this check box since we do not have any html file. 7. Click Finish. You will follow essentially the same steps if you decide to export to an EJS .jar file. The only difference will be the content of the file exported.

Exporting EJBs to Client Jar files


A client jar file contains all the classes and interfaces used to access EJBs. NOTE: If you work as recommended with two different project one for the client and on for the server than instead of adding the server project to the

88

Developing Enterprise JavaBeans with VisualAge for Java

classpath of the client project, we recommend that you include the client jar file in the client classpath before executing the client application. This provides better code isolation between the client and server code. To export an EJB to a client jar file: 1. In the EJBs pane of the EJBs page, select one or more EJB groups or Gibson our case you will just select the ReadCustomerInfo sessionbean). 2. Click mouse button 2, then select Export - Client JAR from the pop-up menu. The Export to an EJB Jar File SmartGuide appears.

Figure 48. Export to an EJB Client jar File

Developing a Session bean

89

As you can see from Figure 48 the content of this dialog is exactly the same of the previous dialog in Figure 47. The meaning of the fields is the same the only difference is the content of the .jar file.

Running the client outside VisualAge for Java


If you want to test the client application outside VisualAge for Java and accessing the enterprise bean running inside VisualAge for Java you need to do the following:
u Export an EJB to a client.jar file u Export client code

Export an EJB to a client.jar file As described in the topic "Exporting EJBs to Client Jar files" export the client .jar file to a file called ReadCustomerInfoCli.jar. Export it to the C:\ root directory. If you decide to export it to a different directory you will need to change the class path accordingly. Export the client code you need to export the content of the following packages: itso.samples.ejb.sessionbean.client itso.samples.ejb.sessionbean.client Export them to a .jar file called client.jar file. We pack all together because we have few classes but the right thing could be to have two different .jar file one for the client code and one for the mode that in our case is the CustomerObject JavaBean only. In the next session assume you have exported the .jar file in the C root directly: You will now have to check you have the following files in the c:\ ReadCustomerInfoCli.jar CustomerObject.jar Client.jar customer.ser Open a DOS prompt check your class path and check you have the following in your classpath:
.; c:\;

90

Developing Enterprise JavaBeans with VisualAge for Java

C:\ReadCustomerInfoCli.jar; c:\CustomerObject.jar; c:\client.jar; c:\WebSphere\AppServer\lib\ejs.jar; c:\WebSphere\AppServer\lib\jndi.jar; c:\IBMVJava\eab\runtime20; c:\IBMVJava\eab\runtime; c:\IBMVJava\eab\runtime20\jdebug.jar; c:\SQLLIB\java\db2java.zip; c:\SQLLIB\java\runtime.zip; c:\swing-1.0.3\swingall.jar

NOTE:
u You should not have to care about VisualAge for Java and DB2 path they

should have been set during the installation procedure of both products but you will for sure need to add manually the one regarding WebSphere.
u If you have exported the jar files to different directories make those

changes to be reflected in the classpath. But remember the customer.ser file has to be in the C:\ root. Make sure the EJB environment is up and running inside VisualAge for Java which mean all EJB servers are started. Run the java client from the DOS Prompt using the following command:
java itso.samples.ejb.sessionbean.client.ReadCustomersClient iron com.ibm.jndi.CosNaming.CNInitialContextFactory 900

Be sure you use the right hostname instead of iron.

3.6 Deployment on WebSphere Advanced Edition 2.0


We see now how to deploy inside WebSphere the ReadCustomerInfo. You are supposed to have WebSphere Advanced Edition 2.0 up and running. We have experienced problem with empty containers inside WebSphere. If you are not going to use a container you should remove it. Since we do not use the defaultEntityContainer, therefore we remove it. To remove a container start IBM WebSphere ApplicationServer 2.0 Administration utility.

Developing a Session bean

91

Figure 49. IBM WebSphere Application Server Administration Login

Login into the administration server. In the left pane choose Enterprise Java Services - Containers. On the right side of the window choose defaultEntityContainer and click Remove. You should now have only the defaultSessionContainer shown in the list.

92

Developing Enterprise JavaBeans with VisualAge for Java

Figure 50. Container Page inside WebSphere.

In Figure 50 you can see the container settings. Container Name field: shows the container name you assigned to the container Container Class files: contains the class name of the container services used by WebSphere. In this case we have com.ibm.ejs.container.EJSSessionContainer for Session Beans. com.ibm.ejs.container.EJSEntityContainer is used for Entity Beans. JDBC URL field: You need to specify this information only if you are defining a container that is supposed to contains Entity Beans in this case you have to specify something like
jdbc:db2:ejs_samp

EJB Jar Directory field: this is the directory where the WebSphere server look to find the jar file deployed in the container. The directory is called deployedEJBs and it is found under: drive:\WebSphere\Appserver directory.

Developing a Session bean

93

Container Database Authentication: in this fields you see the Container User ID and password (which is the same as your DB2 administrator userid and password) Deployed EJB Jar File list: You can see the list of the already deployed jar files. In the left pane select Enterprise Java Services - EJB Jar Files to see which EJBs can be deployed and which have already been deployed. We now want to deploy the ReadCustomerInfo session bean inside WebSphere. 1. From VisualAge for Java go to EJB workspace select the ReadCustomerInfo bean and export it to EJS jar file as described in the topic "Exporting EJBs to EJS or EJB Jar Files on page 85. 2. Export the EJS jar file in the drive:\WebSphere\AppServer\deployableEJBs. following directory.

Call it ReadCustomerInfo.jar. Remember that you also need to export the client .jar file and the client application. As described in Running the client outside VisualAge for Java on page 90.
*** NOTE ***

Before you can deploy the ReadCustomerInfo.jar inside WebSphere you have to make sure that WebSphere has in his class path a reference to the CustomerObject.jar file. If it doesnt you get an error saying it could not read the .jar file when attempting to deploy. The reason why you get this is that the ReadCustomerInfo uses the CustomerObject class which is found in the CustomerObject file. To know how to update WebSphere class path please refer to Appendix A.3, Updating WebSphere Class Path on page 350 3. From Enterprise Java Services select EJB Jar Files. You now see the ReadCustomerInfo.jar file in the EJB Jar File list. 4. Select the ReadCustomerInfo.jar file the content of this file appears in the right pane. 5. Click Deploy button. The following window appear:

94

Developing Enterprise JavaBeans with VisualAge for Java

Figure 51. Deploy Jar File Window

6. Make sure the container selected is the right one (defaultSessionContainer in our case). Click the Deploy button. The following window appear:

Figure 52. Redeployment Selection window

7. The Window in Figure 52 box shows three options: Regenerate which is used for JAR files that have never been deployed; it creates the stubs and skeletons and database tables necessary in a deployed EJB. Redeploy Existing is used for any predeployed samples; it uses the existing stubs and skeletons contained in the JAR file and creates the necessary database tables (only for Entity Bean). Cancel allows you to revert to the previous screen. Since we have exported an EJS jar file from VisualAge for Java the ReadCustomerInfo bean is already deployed. Click Redeploy Existing. If everything is ok with the deployment you get the following message.

Developing a Session bean

95

Figure 53. EJB Jar Copy Window.

8. Logoff from the administration server. Stop and restart your WebSphere Application Server for this to take effect. To stop WebSphere: Shut down the Web server(from Start- Settings- Control PanelServices and select Lotus Domino Go Webserver click the Stop button.) Shut down the WebSphere ServletService to stop Application Server. (Select the WebSphere Servlet Service from StartSettings- Control Panel- Services and push the Stop button.) To start WebSphere: The server starts automatically when you start your Web server(from Start- Settings- Control Panel- Services and select Lotus Domino Go Webserver click the Start button.) You are now ready to test your environment using the ReadCustomerClient application. Open a DOS Window check your classpath as explained inRunning the client outside VisualAge for Java on page 90. From the DOS Prompt run
java itso.samples.ejb.sessionbean.client.ReadCustomersClient iron com.ibm.jndi.CosNaming.CNInitialContextFactory 9019

NOTE: In the VisualAge for Java IDE, the Persistent Name Server runs on port number 900. However, in WebSphere Advanced Edition 2.0, it runs on port number 9019. The port number value can be configured. This is the reason why when you write your client application you need to pass in the right port number.

96

Developing Enterprise JavaBeans with VisualAge for Java

3.7 Deployment for Other Enterprise JavaBeans Servers


If you plan to deploy your EJB in a non WebSphere environment what you have to do is to prepare a ejb-jar as described in Generating Deployed Code on page 55. You can do this with VisualAge for Java choosing the option Export-EJB Jar as shown in Figure 54.

Figure 54. Exporting to EJB Jar files

Developing a Session bean

97

Once you get your new .jar file you can deploy it in any EJB container using the tools the container provide to you. You need to follow the container tool instruction. Just to let you understand which should be the common procedure we will deploy this new .jar file inside WebSphere. In this case we work as VisualAge for Java do not provide us the possibility to export directly to the EJS jar. Before we can deploy the jar again we need to undeploy it. 1. From Enterprise Java Services select EJB Jar Files. You now see the ReadCustomerInfo.jar file in the EJB Jar File list. 2. Select the ReadCustomerInfo.jar file the content of this file appears in the right pane. 3. Click Undeploy button. The following window appear:

Figure 55. Undeploy Jar file window

4. Make sure the container selected is the right one(defaultSessionContainer in our case). Click the Undeploy button. The following window appear:

98

Developing Enterprise JavaBeans with VisualAge for Java

Figure 56. EJB Jar Undeploy Result Window

5. From VisualAge for Java go to EJB workspace select the ReadCustomerInfo bean and export it to EJB jar file as described in the topic "Exporting EJBs to EJS or EJB Jar Files on page 85. 6. Export the EJB jar file in the drive:\WebSphere\AppServer\deployableEJBs following directory.

7. Follow the steps for the deployment again. This time it will take longer since all the EJS files needed to be created. 8. Logoff from the administration server. Stop and restart your WebSphere Application Server for this to take effect.

3.8 Deployment using WebSphere tools


WebSphere Advanced Edition 2.0 provide a tool to manually generate a deployment descriptor file for an enterprise Bean (and place that descriptor file in an existing .jar file). This tool is named jet and can be found under the following WebSphere product path
\WebSphere\AppServer\Samples\ejs\

We will give you an example on how to use the jet tool. To run jet navigate he WebSphere path as window shown in Figure 57

Developing a Session bean

99

Figure 57. WebSphere Navigation Path

Select jet.bat and double click on it. The jet will start and the window shown in will appear.

100

Developing Enterprise JavaBeans with VisualAge for Java

Figure 58. The jet Tool

To generate a deployment descriptor file for an enterprise Bean with the jet tool, do the following: 1. Specify the full path of the .jar file containing your enterprise Bean in the Input field. You can use the Browse button to obtain the file that you need. If you created your input .jar file correctly, all of the fields in either the EntityBean or SessionBean window are filled in with the default deployment descriptor values for your Bean. Try to import the ReadCustomerInfo.jar we used in Deployment for Other Enterprise JavaBeans Servers on page 97. The

Developing a Session bean

101

ReadCustomerInfo.jar is an EJB jar file generated by VisualAge for Java it does already contain a deployment descriptor. This is the reason why you get the following message:

Figure 59. jet Tool Message

Click the Yes button to examine the content of the Deployment descriptor. Your jet tool should now appear like the following

102

Developing Enterprise JavaBeans with VisualAge for Java

Figure 60. The jet Tool after Importing the ReadCustomerInfo Bean

2. Specify the full path of the ejb-jar file to create in the Output field. You can use the Browse button to obtain the file that you need. (If you want to create an XML file containing the descriptor only, specify the full path to that file in the XML Output field. Note that this file is not required.). You generally specify the same name as the input. Here we want jut to see how the .jar file i modified with the deployment descriptor. So just type file name. 3. You can notice that only the SessionBean tab is available for the selection. This is why the tool recognize the type of Bean he is dealing with. Select the SessionBean tag. 4. You can navigate in the jet tool tag and you will discover a match of the information shown with the property dialog in Figure 24 on page 58. To create a deployment descriptor, you must specify appropriate values for

Developing a Session bean

103

the type of Bean you are creating as described in Generate deployment code inside VisualAge for Java on page 64. 5. By selecting the Environment tab, you can modify the property customerFile and assign it a value different from what the developer set during development time (see Figure 26 on page 60). For example, we change the path to access the file customer.ser from: c:\customer.ser to z:\ITSO\SG245429\Redbook\customer.ser as shown in Figure 61:

Figure 61. Using Jet Tool to Modify a Property Value

6. When the attribute and other values are set, press the Build button to build the deployment descriptor file and add that file to the output .jar file For more detail on the jet tool please refer to Websphere Enterprise Server for Java Programming Guide At this point you can deploy your EJB inside WebSphere. During deployment, an ejs-jar file is generated from an ejb-jar file. The ejs-jar file contains the container-specific stub, skeleton, implementation, helper, and holder classes required by the container.

104

Developing Enterprise JavaBeans with VisualAge for Java

The WebSphere EJBDeploy command can be used to manually deploy an enterprise Bean. This command-line tool can also be used to generate the database tables required for entity Beans. The syntax of the EJBDeploy command follows:
java com.ibm.ivj.ejb.tools.deployment.EJBDeploy ejb-jarFile workingDirectory ejs-jarFile[options]

The following command parameters are required: ejb-jarFileIdentifies the ejb-jar input file to be deployed. workingDirectoryIdentifies a working directory that is used by the command to store temporary files during deployment. ejs-jarFileIdentifies the ejs-jar output file to be created during deployment. Optionally, you can specify one or more of the following command parameters to fine tune the actions of the EJBDeploy command:
u -analyzeDirects the command to analyze the contents of the ejb-jarFile

to ensure that it contains all required files and that the classes and interfaces define a valid enterprise Bean.
u -codegenDirects the command to create EJS implementation classes

only; stub and skeleton classes are not generated.


u -dburl dbURLDirects the command to create the specified database

table for use by the enterprise Bean. The argument to this parameter has the following format: dbAPI:database:tableName. For example, to create a database table named sample in an IBM DB2 database with the Java Database Connectivity (JDBC) API, the argument is jdbc:db2:sample.
u -dbuid dbUserIdDirects the command to associate the specified

database user ID with the Bean so that the container can access the database on the Beans behalf. This parameter must be used in conjunction with the -dbpass parameter.
u -dbpass dbPasswordDirects the command to associate the specified

database password with the Bean so that the container can access the database on the Beans behalf. This parameter must be used in conjunction with the -dbuid parameter.
u -forceDirects the command to ignore verification errors (those that can

be discovered by using the -analyze parameter) and create the ejs-jar file.
u -nocleanDirects the command to refrain from deleting the classes

written to the workingDirectory during deployment.


u -t Directs the command to report on its progress during deployment.

Developing a Session bean

105

The follow command deploys the example ReadCustomerInfo.jar ejb-jar file into an ejs-jar file named ReadCustomerInfoEJS.jar using the working directory C:\TestApp:
C:\TestApp> java com.ibm.ivj.ejb.tools.deployment.EJBDeploy ReadCustomerInfo.jar C:\TestApp ReadCustomerInfoEJS.jar

Once you have deployed your enterprise Beans, you have to copy the ReadCustomerInfoEJS in the deployable directory inside WebSphere and follow the steps in Deployment on WebSphere Advanced Edition 2.0 on page 91

106

Developing Enterprise JavaBeans with VisualAge for Java

4 Developing a Container-managed persistence bean


4.1 Container-Managed Persistence basics
As you read in the introduction, a Container-managed persistence (CMP) is an Entity bean for which the container handles the interactions between the enterprise bean and the data source. The container uses the getContainerManagedFields() method from the deployment descriptor to find out which fields it is responsible for. The container is responsible for the instance fields synchronization with the persistent store. When you develop a Container-managed persistence bean you dont have to care about the which type of persistent mechanism is used. This section examines the development of entity Beans with CMP. While much of the information in this section also applies to entity Beans with BMP, there are some major differences between the two types. For

Copyright IBM Corp. 1999

107

information on the tasks required to develop an entity Bean with BMP, see Chapter 5, Developing a Bean-managed persistence bean on page 173.

4.2 Developing a CMP Bean


Typically, the development steps you would follow when using the EJB Development Environment to develop a Container-managed persistence (CMP) enterprise Bean are: 1. Add one or more EJB groups to organize your EJBs using one or both of the following methods: Create new EJB groups. The EJB Group creation is covered in Chapter 3, Developing a session enterprise bean on page 19. Retrieve existing EJB groups from the repository. 2. Populate your EJB groups with EJBs using one or more of the following methods: Import EJBs from EJB jar files. Create new EJBs. Retrieve existing EJBs from the repository. 3. Add the home methods and remote (business) methods to the EJB bean class and then promote them to the home and remote interfaces. (This step can actually be done anytime after your have added your EJBs. However, it must be done before you generate the EJB deployed classes.) In this chapter, we explain the addition of home and remote methods before the insertion of CMP fields. 4. Add, define, and map any required CMP fields: 1. Add required fields to the EJBs. 2. Define CMP fields and the key field for the CMP entity EJBs. 3. Map the CMP fields by doing one of the following: Generate a default database schema, this approach is called Top-down. Map CMP fields to an existing database table (meet in the middle) by either: Importing a schema from an existing database table and mapping the CMP fields to it. Creating a new schema, using it to create a new table, and mapping the CMP fields to it.

108

Developing Enterprise JavaBeans with VisualAge for Java

5. Set your Deployment descriptors. (This step can be done anytime after you have added your EJBs. However, it must be done before you test/deploy your EJBs.) 6. Generate the EJB deployed classes. 7. Test the EJBs. 1. Create an EJB server configuration. 2. Start the DB2 servers (if testing entity beans). 3. Create any required database tables. 4. Start the Name Service and Location Daemon servers and the EJB server. 5. Generate an EJB test client. 6. Run the EJB test client. In this chapter we create a sample Customer EJB, add methods to their remote and home interfaces, add CMP fields, create an empty DB2 database, map the CMP fields to the database tables (using the meet in the middle approach), set the Deployment Descriptors, generate the deployed code and test the Bean.

Creating a Container-managed persistence bean


To start select the EJB group you want to insert your EJB into. To add EJBs to this group: 1. In the EJBs list, click on the ITSOEJBGroup EJB Group. This is the EJB Group we created in , First step: adding EJB Groups on page 29. 2. Click the mouse button 2. From the pop-up menu, select Add - EJB. The Create EJB SmartGuide appears (see Figure 62).

Developing a Container-managed persistence bean

109

Figure 62. The SmartGuide Window

As you can see using the Create EJB SmartGuide, you can add an EJB by either creating a new EJB or by retrieving one or more existing EJBs from the Repository. To add an EJB by creating a new EJB:

110

Developing Enterprise JavaBeans with VisualAge for Java

1. Ensure that the Create a new Bean Class radio button is selected. 2. In the Bean name field, type in Customer which is the name that you want to assign to your new EJB. 3. Since you are creating a new EJB bean class, you need to specify the type of EJB you want to create. The Customer is a Container-managed persistence Bean so from Bean type drop-down list choose Entity Bean with container-managed persistence fields (CMP). 4. In the Project field, you can type the project name, modify the default name, or click the Browse button and select the project that will contain the EJB bean class. If you type a project name that does not exist, VisualAge for Java will not let you create your Bean, see Figure 63. By default, the project to which the EJB group belongs is displayed. In our case we use the default project, which is ITSO Bank.

Developing a Container-managed persistence bean

111

Figure 63. Project not Found

5. In the Package field, you can type the package name, modify the default name, or click the Browse button to select the package that will contain your EJB bean. If you enter a package that does not exist,

112

Developing Enterprise JavaBeans with VisualAge for Java

a new package is created. Type itso.samples.ejb.CMP in the package field. 6. In the Class field, either accept the default value or type in a name for the new class. We recommend that you use the default value so that all the implementation types of the EJB are named properly 7. Since we do not provide any superclass for our Customer bean we do not fill the Superclass field. Your SmartGuide should look like Figure 64.

Developing a Container-managed persistence bean

113

Figure 64. Create EJB SmartGuide

114

Developing Enterprise JavaBeans with VisualAge for Java

Click on Next > to go to the next page of the Create EJB SmartGuide. Your screen should now look like Figure 65.

Figure 65. EJB Class Attributes and Interfaces Definition

8. We use the default names in our Customer example for the EJB Home Interface, EJB Remote Interface and EJB Key Class or Field so we dont change their values. If you wish to use your own Home Interface,

Developing a Container-managed persistence bean

115

Remote Interface or the KeyClass names you can change them in this window. The Create finder helper interface to support finder methods checkbox, tells VisualAge for Java to generate the CustomerBeanFinderHelper method. We need the CustomerBeanFinderHelper to add a special finder on the Customer Beans. If you dont need any other finder than the getByPrimaryKey for your Bean, you dont need to check this option. If you need to implement specific import and/or interfaces in your Bean, select them using the appropriate buttons. The Create method stubs which must be implemented (Recommended) checkbox ensure that stubs are created for the methods declared in the interfaces you selected. 9. Click on Finish to generate the classes you need to develop the Customer implementation. Now, your Workbench should look like Figure 66.

116

Developing Enterprise JavaBeans with VisualAge for Java

Figure 66. Customer CMP Entity Bean Generated Classes

As you can see in Figure 66, VisualAge for Java generates 5 different types for you. These types are respectively:
u Customer interface (the remote interface) u CustomerBean class (the Entity Bean) u CustomerBeanFinder interface

Developing a Container-managed persistence bean

117

u CustomerHome interface and u CustomerKey class

VisualAge for Java automatically creates according to the EJB specification these 5 classes required for a Container-managed persistence EJB .

Projects, packages and reserved package organization


Whenever you add an EJB group to the EJBs page, a reserved package is created under the project in the following form <EJB_group_name>EJBReserved (for example in our case VisualAge for Java creates the reserved package ITSOEJBGroupEJBReserved). 1. Click on the Projects page. 2. Expand the ITSO Bank project and check that ITSOEJBGroupEJBReserved package has been created. This reserved package is used to hold Java classes that represent your EJB objects and their associated meta data. Although the EJB is represented as a class in the reserved package, you cannot see the EJB source code because all information associated with the EJB object is saved as the meta data of the corresponding class. For this reason, you should always use the EJBs page to edit your EJB source code and should never attempt to directly delete, replace, reorganize, or otherwise manage the classes contained in the reserved package of the project. We created another package itso.ejb.samples.CMP to contain our bean code, schemas and maps. These two packages are included in the ITSO Bank project. 3. Click on the EJBs page to get back to the EJB development Environment. The association between the EJB reserved package and the project is done at the creation of the EJB Group see Figure 67.

118

Developing Enterprise JavaBeans with VisualAge for Java

Figure 67. Association between EJB Reserved Package and Project.

The association between the project and the package containing our bean code, schemas and maps is made at the creation of the EJB Bean, see Figure 68.

Developing a Container-managed persistence bean

119

Figure 68. Association between EJB Class package and Project

Understanding the generated types


u Customer interface

The Customer interface is the remote interface for the CustomerBean EJB object. The Customer Beans remote interface provides access to the business methods available in the CustomerBean class. By convention, the remote interface is named Name, where Name is the name you assign to the enterprise Bean. For example, the Customer enterprise Beans remote interface is named Customer. The Customer remote interface is covered in detail in topic 4.4, Adding remote interface methods on page 137.
u CustomerBean class

The CustomerBean class represents the Entity Bean. It must implement the business methods used to access and manipulate the data associated with the enterprise Bean.

120

Developing Enterprise JavaBeans with VisualAge for Java

It must define and implement an ejbCreate method for each way in which the enterprise Bean can be instantiated. A corresponding ejbPostCreate method must be defined for each ejbCreate method. A thumb rule for deciding the parameters for an ejbCreate method: all the non-nullable fields should be inititalized from the parameters so that there is no exception at the persistence store end. For example, when using RDBMs, if a row is inserted into a table with null values for columns declared as non-nullable, the RDBMs will throw an exception. The CustomerBean class defines and implements the business methods of the Customer enterprise bean, defines and implements the methods used to create instances of the Customer enterprise Bean, and implements the methods used by the container to inform the instances of the enterprise Bean of significant events in the instances life cycle (callbacks methods). By convention, the enterprise Bean class is named NameBean, where Name is the name you assign to the enterprise Bean. The enterprise Bean class for the example Customer enterprise Bean is named CustomerBean.
u CustomerBeanFinderHelper interface:

The CustomerBeanFinderHelper interface is used by the container to generate the necessary code for querying the database on custom filters. You use the special finder methods to retrieve instances from the database, using other search criteria than the primary key value (for example a search by customers last name). For each finder method defined in the home interface (CustomerHome) other than the create and findByPrimaryKey methods, you are responsible to define the corresponding query string. The topic 4.5, Modifying, adding home methods on page 140 explains how to add finder methods.
u CustomerHome interface:

The CustomerHome interface is the home interface for the Customer entity Bean. An entity Beans home interface defines the methods used by clients to create new instances of the Bean, find, remove existing instances, and obtain meta data information about an instance. This home interface is implemented by the EJB home class generated by the containers deployment tool. The container registers the home interface into the naming tree allowing EJB clients to access it using the JNDI API. By convention, the home interface is named NameHome, where Name is the name you assign to the enterprise Bean. For example, the Customer enterprise Beans home interface is named CustomerHome. The topic 4.5, Modifying, adding home methods on page 140 covers the Home interface.

Developing a Container-managed persistence bean

121

u CustomerKey class:

Every enterprise entity bean has a unique identity within a container that is defined by using a combination of the objects home interface name and its primary key and assigned at object creation time. If two EJB objects have the same identity, they are considered identical. The bean key class is used to encapsulate a primaryKey. By convention, the bean key class is named NameKey, where Name is the name of the enterprise Bean. For example, the Customer enterprise Beans primary key class is named CustomerKey. It must be public and it must be serializable. Its instance variables must be public and the variable names must match a subset of the variable names defined in the enterprise Bean class. The CustomerKey class is an object generated by VisualAge for Java to help you creating new instances and finding existing instances of the Customer entity bean from the database. This CustomerKey object is a unique representation of the Customer. The methods from the CustomerHome interface using it: create(CustomerKey) findByPrimaryKey(CustomerKey) methods generated for the CustomerKey are described in the topic 4.3, Understanding the generated methods on page 132.

Adding fields to the Bean


In order to enrich the customer bean, we add the fields: firstName and lastName. 1. In the EJBs list, select Customer and click on the fields icon located at the upper right corner of the Types listbox. This toggles the listbox name from Types to Fields. It also modify the content of the listbox and displays fields for the selected EJB. If you dont see any, ensures you have the Customer EJB selected. Your screen should look like Figure 68.

122

Developing Enterprise JavaBeans with VisualAge for Java

Figure 69. CustomerCMP Entity Beans Fields

VisualAge for Java automatically creates two fields:


u entityContext and u primaryKey.

Now we add two additional fields firstName and lastName. 1. In the EJB list of the EJBs page, select the Customer EJB bean.

Developing a Container-managed persistence bean

123

2. You need to display the classes by clicking on the Types icon

3. Select the CustomerBean class, click mouse button 2 in the types list. Select Add Field from the pop-up menu. The Create Field SmartGuide appears. 4. Fill in with the following informations, Field Name is firstName, Field Type is java.lang.String. All the CMP Fields of a CMP Entity Bean must be public, so the Access Modifiers has to be public. Mark the Access with setter and getter methods check box as checked and select in the setter and getter group boxes the public radio buttons. Your screen should look like Figure 70. Other Modifiers group box options are described in the topic , Regarding the other modifiers (final, transient, static) on page 129.

124

Developing Enterprise JavaBeans with VisualAge for Java

Figure 70. Create Field SmartGuide

5. Click Finish. 6. Repeat steps 3 and 4 for two additional fields: lastName and dummy. 7. Click on the Fields icon to see the newly created fields: dummy, firstName and lastName, in your CustomerBean entity Bean, see Figure 71.

Developing a Container-managed persistence bean

125

Figure 71. New Fields Created

The idea with Container-managed persistence EJB is to let the container handle all of the database interactions involved with the creation, read, update and deletions of EJB. In order to achieve this, you need to identify which are the fields you want to be Container-managed persistence fields. Each of these identified CMP fields are persistent in a database record field. The container determines which fields are of Container-managed persistence type by calling the getContainerManagedFields() method of the entity descriptor which returns a Field[] array. VisualAge for Java lets you identify which fields are container managed. To define dummy, firstName and lastName as CMP fields: 1. Select dummy field press and hold on the Ctrl key on the keyboard and click with mouse button 1 on firstName and lastName. 2. Click on mouse button 2 and select Container Managed. An icon appears on the right side of dummy, firstName and lastName indicating that they are Container-managed persistence fields, see Figure 72.

126

Developing Enterprise JavaBeans with VisualAge for Java

Figure 72. CMP Fields Icon

The code you provide in your beans does not contain any database access, creation and updates. VisualAge for Java generates the necessary code at deployment time for you. VisualAge for Java also generates all the accessors (getter and setter). These methods are described in topic 4.4, Adding remote interface methods on page 137.

Removing a field
In this section we show you how to remove the dummy CMP field from the Customer CMP Bean. 1. Click on the dummy field from the Fields list. Click on mouse button 2 and deselect Container-Managed. 1. From the Methods list, you need to click on the getDummy() method. Press the Ctrl key on the keyboard and select the setDummy() method as well. 2. Click on the mouse button 2, select Delete. 3. VisualAge for Java ask you for a deletion confirmation, click Yes. 4. You just have deleted the getter and setter methods for the field you want to delete.

Developing a Container-managed persistence bean

127

5. You need to click on the Customer EJB from the EJBs list to see the Class definition in the source window. You need to delete the dummy field declaration from the source window, see Figure 73.

Figure 73. Dummy Member Field Declaration

6. Press Ctrl-S to save your Customer Bean. The dummy field disappears from the Fields list. Your Workbench now looks like Figure 74.

128

Developing Enterprise JavaBeans with VisualAge for Java

Figure 74. Workbench without Dummy Field

Regarding the other modifiers (final, transient, static)


u final modifier can be used on fields which will not change in their

lifetime. If you select the final modifier, VisualAge for Java will not generate a setter method for the field, but it will generate a getter method. This means, you will be able to retrieve the value of the field, but you will be not able to set it. This final CMP field should be initialized properly in the ejbCreate method. You can use a final CMP field to store a constant value in from your database into a member attribute of your CMP Entity Bean.
u static modifier is not supported by CMP fields. u volatile u transient modifier can be used for local variables. The transient

modifier basically means that the CMP member field is not persisted to the database. For example, assume a field contains the result of a long calculation. A remote method needs this field several times during its execution. Instead of calling the fields getter methods several time, we can use a CMP transient field to store its value. This way we save CPU processing time. This is illustrated in Figure 75.

Developing a Container-managed persistence bean

129

Figure 75. Transient Field Modifier Utilization Example

Working with the key Class


When you create an entity bean, a default key generation is done. This generated key has been explained in the topic , Understanding the generated types on page 120. There are 3 different things you can do with this default key class: use it as it is modify it by adding additional fields to it redefine it to use other field(s) In our example, we add the lastName field to the primaryKey object.

Adding the lastName field to the CustomerKey


1. Select the customer EJB. 2. Select the lastName from the fields list. 3. Click mouse button 2 and select Key Field from the pop-up menu. Two things happen, in addition to the Container-managed persistence icon, the key icon is added to the lastName field and the lastName field is added to the CustomerKey class. 4. You then need to initialize the lastName member in the ejbCreate method. Click on the Types icon from the Fields list. Select the CustomerBean in the Types list. Select the ejbCreate(CustomerKey) from the Methods list. The following code segment is displayed in the Source window:
/**
* ejbCreate method comment for a CMP entity bean * */ public void ejbCreate(CustomerKey key) { // All CMP fields should be intialized here. primaryKey = key.primaryKey;

130

Developing Enterprise JavaBeans with VisualAge for Java

5. Add the following line:


lastName = key.lastName;

6. Press CTRL-S to save your method. Each time you create a Customer EJB using its CustomerKey object, the proper key fields (primaryKey and lastName) are initialized properly.

Redefining the key Class


If you need to use another object than the one generated as key, you can do it following these tasks (be careful when you do this because VisualAge for Java does not provide you with an automatic mechanism to replace a key, you do have to replace some definitions and references): 1. In the EJBs pane of the EJBs page, select the bean for which you want to redefine the primaryKey. 2. In the upper right corner, click on the Fields icon to toggle to the fields list. 3. Select the field named primaryKey. 4. Click mouse button 2 and deselect Container Managed setting from the pop-up menu. 5. Toggle to the types list by clicking the Types icon. 6. Select CustomerBean from the Types list to show the class definition. Delete the primaryKey field from the class definition of the bean and then save the class. 7. Select the ejbCreate method. Delete the primaryKey initialization from the ejbCreate method. Press CTRL-S to save your method. 8. Add your new primary key field using the Create Field SmartGuide. Click the Fields icon from the Types list. Go in the field list and select your newly created key field. Click mouse button 2 then select Key from the pop-up menu and save. 9. Click on the Types icon, to display all the Types list. Select your newly created key object from the Types list. If your newly created key has a different type than the previous one: 1. Delete the ejbCreate method which uses the older primaryKey member. 2. Select the ejbCreate method of your EJB from the Methods list. Initialize your newly created key member field in your EJB. 10.Save your method.

Developing a Container-managed persistence bean

131

11. You can now work with your newly created key.

4.3 Understanding the generated methods


VisualAge for Java automatically creates some methods for you. These methods are mapped to the methods described in the contract for the entity Beans with Container-managed persistence section of the Enterprise JavaBeans specifications. We give here the different Container-managed persistence generated methods, for the following types: The CustomerBean class. The CustomerHome interface. The CustomerKey class. Note that there no generated methods for the Customer and CustomerFinderHelper methods when you create a new CMP Entity Bean. The methods in the Customer interface are covered in the topic 4.4, Adding remote interface methods on page 137 and the addition of special finder methods in the CustomerFinderHelper is covered in topic 4.5, Modifying, adding home methods on page 140. To help understanding the generated methods, we need first to look into the lifecycle of an Entity Bean.

Life cycles of enterprise Bean instances


Once an enterprise Bean is deployed into a container, clients can create and use instances of that Bean as required. Within the container, instances of an enterprise Bean go through defined life cycle. The events in an enterprise Beans life cycle are derived from actions initiated by either the client or the container. You must understand this life cycle, because for some enterpriseBeans, you must write some of the code to handle the different events in the enterprise Beans life cycle.

Creation State
An entity Bean instances life cycle begins when the container creates that instance. After creating a new entity Bean instance, the container invokes the instances setSessionContext method. This method passes the Bean instance a reference to an entity context interface that can be used by the instance to obtain container services and get information about the caller of e client-invoked method.

132

Developing Enterprise JavaBeans with VisualAge for Java

Pooled State
Once an entity Bean instance is created, it is placed in a pool of available instances of the specified entity Bean class. While the instance is in this pool, it is not associated with a specific EJB object. Every instance of the same enterprise Bean class in this pool is identical. While an instance is in this pooled state, the container can use it to invoke any of the Beans finder methods.

Ready State
When a client needs to work with a specific entity Bean instance, the container picks an instance from the pool and associates it with the EJB object initialized by the client. An entity Bean instance is moved from the pooled to the ready state if there are no available instances in the ready state. There are two events that cause an entity Bean instance to be moved from the pooled state to the ready state: When a client invokes the create method in the Beans home interface to create a new and unique entity of the entity Bean class (and a new record in the data source). As a result of this method invocation, the container calls the Bean instances ejbCreate and ejbPostCreate methods and the new EJB object is associated with the Bean instance When a client invokes a finder method to manipulate an existing instance of the entity Bean class (associated with an existing record in the data source). In this case, the container calls the Bean instances ejbActivate method to associate the Bean instance with the existing EJB object. When an enterprise Bean instance is in the ready state, the container can invoke the instances ejbLoad and ejbStore methods to synchronize the data in the instance with the corresponding data in the data source. In addition, the client can invoke the Bean instances business methods when the instance is in this state. All interactions required to handle an entity Bean instances business methods in the appropriate transactional (or non transactional) manner are handled by the container, unless the EJB developer has decided to handle these interactions. When a container determines that an entity Bean instance in the ready state is no longer required, it moves the instance to the pooled state. This transition to the pooled state results from either of the following events: When the container invokes the ejbPassivate method. When the client invokes a remove method on the EJB object associated with the Bean instance or on the EJB home object. When one of these 133

Developing a Container-managed persistence bean

methods is called, the underlying entity is removed permanently from the data source.

Removal State
An entity Bean instances life cycle ends when the container invokes the unsetEntityContext method on a entity Bean instance in the pooled state. Do not confuse the removal of an entity Bean instance with the removal of the underlying entity whose data is stored in the data source. The former simply removes an uninitialized object, the latter removes data from the data source.

The CustomerBeans generated methods


You can see the generated methods in the Methods list of the CustomerBean Class. public void ejbActivate(); This life-cycle call-back method of the entity bean is invoked when the container assigns an instance from the pool to a specific EJB object identity. This signals the ready state for the enterprise bean. You can use this method to load additional resources in the bean. If you need to do one-time initialization on non-CMP fields from your CMP Bean, you could use this callback method to do this. For example, we used the ejbActivate in our Bank inheritance implementation to initialize the Proxy object (see Chapter 11, Inheritance on page 265). public void ejbCreate(CustomerKey key); VisualAge for Java generates a default ejbCreate(...) method which takes the EJB Key class, CustomerKey, as a parameter. This signature matches the create(...) method of the beans home interface. It is your responsibility to: Initialize the instances variables (like we did when we inserted the lastName field in the CustomerKey object). It is the container responsibility to: Create an entry representing the entity in the persistence store. The return value must be void for entity beans with Container-managed persistence. You may have expected a Customer object being returned? In fact, a client does not access directly the ejbCreate but instead it calls the Home interface create() method which does return a Customer object (see Chapter , The CustomerHome interfaces generated methods on page 136). public void ejbLoad(), public void ejbStore() 134

Developing Enterprise JavaBeans with VisualAge for Java

We describe these two methods at the same time, since their utilization is quite similar. The EJB Specifications from Sun are quite vague on this ejbLoad and ejbStore methods. They say that: "..., the container can invoke the ejbLoad() and ejbStore() methods one or more times, at anytime. " (section 9.3 - Instance Lifecycle, p.62) "The purpose of the ejbLoad method is to synchronize the state of the instance with the state of the entity in the underlying data source" (section 9.3 - Instance Lifecycle, p.62) Let us give you a clear understanding of what these two points mean with VisualAge for Java and WebSphere. First, for all CMP fields in your CMP Bean, you dont have to care about the CMP fields state synchronization with the data store, since the container takes care of it. This means for CMP fields, you dont need to add any code to these callback methods. WebSphere always call ejbLoad() after a new transaction has been started, and after you invoke a method from the remote interface. If you have any non-CMP fields in your CMP Bean which always needs the latest state (like stock tickers), you should use the ejbLoad() callback method to initialize them. The ejbStore is called after a transaction has been committed. public void ejbPassivate(); The EJB container invokes this method when it decides to send the instance to the pooled state based on a least recently used algorithm. With VisualAge for Java and WebSphere this means, your instance is disassociated from its EJB Object after a defined period (time-out). You can use this method to release any resources that were allocated in the ejbActivate() method. public void ejbPostCreate(CustomerKey key); This life-cycle callback method indicates that the EJB Object identity is available. For each ejbCreate(...) method, there is a matching ejbPostCreate(...) method with the same input parameters. If you add an ejbCreate() to the Entity Bean, you need to add an ejbPostCreate() method as well with matching parameters. public void ejbRemove(); This method is invoked by the container when the client invokes the remove method on an EJB object reference. You can use the ejbRemove method to implement actions you want to take place before the instance is removed from the database. The record is deleted from the

Developing a Container-managed persistence bean

135

database after ejbRemove returns. You dont have to implement the logic to remove the entity from the persistence store, the container takes care of it. public void setEntityContext(EntityContext ctx); public void unsetEntityContext(EntityContext ctx); These two methods are explained in the topic , Life cycles of enterprise Bean instances on page 132.

The CustomerHome interfaces generated methods


To see the CustomerHome interfaces generated methods, click on the CustomerHome interface from the Types list. public Customer create ( itso.ejb.samples.CMP.CustomerKey primaryKey) throws javax.ejb.CreateException, java.rmi.RemoteException; A create method is used by a client to create an enterprise Bean instance and insert the data associated with that instance into the data source. Each create method must be named create and it must have the same number and types of arguments as the corresponding ejbCreate method in the enterprise Bean class. The return types of the create method and its corresponding ejbCreate method are always different, for example in our case the create method returns a Customer while the ejbCreate returns nothing. Each create method must meet the following requirements: It must be named create. It must return the type of the enterprise Beans remote interface. For example, the return type for the create methods in the CustomerHome interface is Customer. It must have a throws clause that includes the java.rmi.RemoteException exception, the javax.ejb.CreateException exception, and all of the exceptions defined in the throws clause of the corresponding ejbCreate and ejbPostCreate methods. When you create a new CMP Bean, VisualAge for Java creates this default create method for you. All of the above requirements are respected. VisualAge for Java automates this task for you. public Customer findByPrimaryKey (itso.ejb.samples.CMP.CustomerKey primaryKey) throws java.rmi.RemoteException, javax.ejb.FinderException; A finder method is used to find one or more existing entity EJB objects. At minimum, each home interface must define the findByPrimaryKey

136

Developing Enterprise JavaBeans with VisualAge for Java

method that enables a client to locate an EJB Object by using the primary key only. VisualAge for Java creates this default finder method automatically for you. We have in our example a findByPrimaryKey which uses a CustomerKey object to identify a particular entity. The findByPrimaryKey returns the type of the CustomerBean remote interface Customer.

The CustomerKeys generated methods


VisualAge for Java creates 4 methods for the CustomerKey class: a default constructor CustomerKey, a constructor which takes the primaryKey and lastName as arguments, an equals method and a hash method. A primary key class is used to create and manage the primary key for an EJB object. The primary key class must meet the following requirements: It must have a public default constructor, at minimum. It must have an equals and a hashCode methods that provide the same functionality for the primary key class as these methods provide for classes such as java.lang.String. In the primary key class for the Customer enterprise Bean, CustomerKey, we have those two methods. The hashCode method for the CustomerKey class simply invokes the corresponding hashCode method in the primaryKey and lastName member fields. In addition to the default constructor, the CustomerKey class also defines a constructor that sets the value of the primaryKey and lastName variables to specified string parameters. The equals method is called on a CustomerKey instance and is passed another CustomerKey instance as parameter. The method compares all the members of the two CustomerKey objects and return true or false. This defines whether the two Customer instances are identical or not.

4.4 Adding remote interface methods


The business methods you want to access from your beans have to be defined in the remote interface. The remote interface describes the entity beans business methods which are accessible by a client. Every remote interface must meet the following requirements:

Developing a Container-managed persistence bean

137

1. It must extend the javax.ejb.EJBObject interface. The EJBs remote interface inherits several methods from the javax.ejb.EJBObject interface. VisualAge for Java takes care of this for you. See topic , Methods inherited from javax.ejs.EJBObject on page 139 for information on these methods. 2. Each method implemented in the enterprise bean class that needs to be accessed by a client must appear in the remote interface. VisualAge for Java automates this task. 3. The parameters and return value of each method defined in the interface must be a valid Java RMI type. For more information, see topic , Using valid parameters and return values for Java RMI on page 140. In this section we will add 4 methods to the remote interface. Two methods to get information from the Bean and two other to update information in the Bean. VisualAge for Java generated these methods for us when we created the fields. The steps to add them to the remote interface are: 1. select the CustomerBean Class in the Types list, this displays its corresponding methods. 2. select the getFirstName method and click mouse button 2. Choose Add To - EJB Remote Interface. The method is marked with an icon indicating the method has been added to the Customer remote interface. 3. to select multiple methods, press the Ctrl key on the keyboard and click each of the methods you want to select: getLastName, setFirstName, setLastName. Click mouse button 2 and select Add To - EJB Remote Interface. Your Types and Methods panes should look like Figure 76.

138

Developing Enterprise JavaBeans with VisualAge for Java

Figure 76. Methods added to the Remote Interface are identified by an Icon

4. To see where VisualAge for Java added your remote methods, select the Customer interface from the Types list. You see the 4 methods in the Methods list, see Figure 77.

Figure 77. Remote Interface generated Methods

Methods inherited from javax.ejs.EJBObject


The remote interface inherits javax.ejs.EJBObject interface: the following methods from the

getEJBHomeReturns the enterprise Beans home interface.

Developing a Container-managed persistence bean

139

getHandleReturns the handle for the EJB object. getPrimaryKeyReturns the EJB objects primary key. isIdenticalCompares this EJB object with the EJB object argument to determine if they are the same. removeRemoves this EJB object. These methods have the following syntax: public abstract EJBHome getEJBHome(); public abstract Handle getHandle(); public abstract Object getPrimaryKey(); public abstract boolean isIdentical(EJBObject obj); public abstract void remove(); These methods are implemented by the container (WebSphere Advanced Edition 2.0) in the EJB object class.

Using valid parameters and return values for Java RMI


To be valid a methods arguments and return value must be serializable. If you attempt to use a parameter that is not serializable, the NotSerializableException exception is thrown. Most of the classes in the java.lang and java.util packages are already defined as serializable. You can make your own classes serializable by implementing the java.io.Serializable interface.

4.5 Modifying, adding home methods


Home interface methods lets you create and search for your entity beans. VisualAge for Java generates the create method for you based on the primary key object. The EJB specification say the container provider has to generate the finder methods for the CMP Entity Beans. VisualAge for Java generates the finder methods at Bean deployment time. Here are the steps you need to do to describe the finder methods: For each finder method defined in the home interface, other than findByPrimaryKey method, a query string must be defined. This query string is an SQL-prepared statement which is executed at run time by the EJB server to locate the EJB(s) as per the finder methods requirements.You have

140

Developing Enterprise JavaBeans with VisualAge for Java

to write a description of this finder method in the <name>BeanFinderHelper interface in order to let VisualAge for Java know what to generate. We describe how to describe and generate a finder method for the Customer Bean in topic 4.9, Adding Special Finder methods on page 160.

4.6 Generating Database Schema and mapping


Before you can execute and test your enterprise Beans you need to map your CMP beans fields to your database structure. In the case of the Cutomer bean, we want to do the folowing mapping:
u primaryKey = CUSTID u lastName = LNAME u firstName = FNAME

as shown in Figure 78.

Developing a Container-managed persistence bean

141

Figure 78. Association Between CMP Fields and Database Columns

With VisualAge for Java you make an association between CMP fileds and database columns by using two different browsers :
u Schema Browser and u Map Browser

With the Schema Browser you first define a schema by giving it a name (SCHEMA1). This schema must be associated to a given database (Database1). From this database you select all or a subset of tables (table1 and Table4). Then for each column you may accept or change the converter that transforms DB2 to Java data types (see Figure 79).

142

Developing Enterprise JavaBeans with VisualAge for Java

Figure 79. Selection with Schema Browser: Database, Tables, Converters

After this has been done, you use the Map Browser to associate CMP fields and columns. Once again, you need to give a name to your map (MAP1). Then you associate this map to a given schema (SCHEMA1). By doing this, the mapping possibilities are limited to those defined in the schema. You make another association between the map you are working with and a given EJB group. Then each CMP bean of this EJB group is associated to one and only one of the tables defined in the schema (CMP1 to Table 4, see Figure 80). The next operation consists in linking each field with a column in a simple or complex Map Type. In a simple Map type, a field is associated to only one column. In a complex Map Type, a field can be associated to more than one column. Figure 80 describes the relationship between the different elements and browsers involved in CMP field to column mapping.

Developing a Container-managed persistence bean

143

Figure 80. With Map Browser Associate Fields and Columns

The EJB Development Environment from VisualAge for Java allows top-down, bottom-up, and meet-in-the-middle mapping of EJBs to database tables. In our Customer example, we cannot use the top-down approach since WebSphere does not support primary key objects with more than one field, and we have two fields (primaryKey and lastName) in our CustomerKey class. We will use the meet-in-middle approach.

The top-down approach


The top-down approach can be used to quickly create simple table and field definitions in your database server. The top-down approach for mapping EJBs to database assumes you have existing EJBs and no existing database structure, for example you created a new CMP bean and you want to generate a database table which corresponds to it, the CMP fields are mapped to the table field. The generated code creates SQL code in the bean class so that the default database tables can be created for the bean class. This supplies a default mapping between the bean and the database table. If you want to use the top-down approach you need to follow these steps:

144

Developing Enterprise JavaBeans with VisualAge for Java

1. Select your EJB Group and click mouse button 2. From the popup window, select Generate->Deployed Code. This is going to generate all the classes required to execute the EJB in the WebSphere Advanced Edition 2.0 container. 2. Select the EJB Group for which you want to create the database tables. Click mouse button 2 and select Add To - Server Configuration. 3. Select your EJB Server from the Servers list and click on mouse button 2, select Properties, see Figure 81.

Figure 81. EJB Server Properties

4. Enter the JDBC database path in the Database URL (in this version of WebSphere Advanced Edition 2.0, you cannot change the default value sampleDB). The database you specify here must exist in order to get a successful tables and fields generation. Click OK. 5. Select your EJB Server from the Servers list and click on mouse button 2, select Create Database Table from the pop-up menu. When the focus returns to the EJB Server Configuration window, your database table has been created (see Figure 82). Then, you can start your server and test it.

Developing a Container-managed persistence bean

145

Figure 82. Characteristics of DB2 Table and Columns Created for CMP Fields

For each bean class a table is generated. In each table definition, a column is defined for each container-mapped field of the bean class. The container-managed fields are mapped as described in Table 1 on page 146. Table 1. Container-Managed fields mapping
CMP fields Java type java.lang.String short or java.lang.Short int or java.lang.Integer float or java.lang.Float double or java.lang.Double byte or java.lang.Byte long or java.lang.Long char or java.lang.Character Mapped Java type String short int float double short String String SQL Type VARCHAR(251)* SMALLINT INTEGER FLOAT DOUBLE SMALLINT VARCHAR(22) CHAR(1)

146

Developing Enterprise JavaBeans with VisualAge for Java

CMP fields Java type boolean or java.lang.Boolean java.math.BigDecimal java.sql.Date java.sql.Time java.sql.Timestamp Other

Mapped Java type short java.math.BigDecimal java.sql.Date java.sql.Time java.sql.Timestamp serialized

SQL Type SMALLINT NUMERIC DATE TIME TIMESTAMP BLOB(1M)**

* Strings are limited to 251 characters in length due to DB2 restrictions dealing with varying length data types and their use in primary key types and certain SQL clauses. ** Non-primitive java types are stored as serialized instances in the database using BLOB data types.

The bottom-up approach


If you already have an existing database structure and you want to reuse it with your EJBs, here is what you can do using the bottom-up approach. In this approach, you need to: 1. import the database schema from the database into the EJB Development Environment using the Schema Browser, describe in topic , Importing a database schema into VisualAge for Java on page 148. 2. create EJBs on the EJBs page as described in topic , Creating a Container-managed persistence bean on page 109. 3. define a map between the EJBs and schema using the Map Browser which is defined in topic , Defining a map between the EJBs and the database schema on page 153.

The meet-in-middle approach


The meet-in-the-middle approach for mapping EJBs assumes that you have existing EJBs and an existing database. To complete the mapping you: 1. import the database schema from the database into the EJB Development Environment using the Schema Browser, describe in topic , Importing a database schema into VisualAge for Java on page 148.

Developing a Container-managed persistence bean

147

2. define a map between the EJBs and schema using the Map Browser which is defined in topic , Defining a map between the EJBs and the database schema on page 153.

Creating the CMP sample database


The utilisation of Schema Maps and Database Schemas browsers is based on the usage of a DB2 database. Before we continue, we invite you to install this database provided with this book. The required files can be found either in the cdrom or the zip file that you have downloaded from the ITSO web site. 1. There are several ways to create the database and populate the corresponding tables. One way is to open a DB2 window. This is done by going to Start->Programs->DB2 for Windows NT->Command Window. From the command prompt change to the directory where you copied the following files from the cdrom\Part1Samples\CMP: CMP.DDL CMP.SQL 2. Enter db2 -f CMP.DDL and hit Enter. This creates the CMPS database and CUSTOMER table. 3. When the command completes, enter db2 -f CMP.SQL and hit Enter. This populates the CUSTOMER table. 4. Type exit and hit Enter to close the DB2 command window.

Importing a database schema into VisualAge for Java


The Schema Browser is used to describe the schema of the relational database into which the persistent classes are stored. To import a database schema into VisualAge for Java you first need to start the Schema Browser: 1. Select the Customer EJB from the EJBs list. Select the EJBs menu. Select Open To - Database Schema. You should see the Schema Browser Window like in Figure 83.

148

Developing Enterprise JavaBeans with VisualAge for Java

Figure 83. Schema Browser Window

The Schema Browser window is divided in 5 sections: the schemas list lets you interact with schemas, the tables display a schemas tables and the columns and foreign key relationships panes are associated with a selected table. The bottom part gives some information and statistics according to what is selected in the top panes. To import our Customer Table schema: 1. Click the mouse button 2 in the Schemas list and select Import / Export Schema - Import Schema from the Database. 2. You then need to give a name to your schema, in our example we use the same name as the Customer EJB class name. Enter Customer then click OK. 3. VisualAge for Java will display the Database Connection Info dialog. Enter COM.ibm.db2.jdbc.app.DB2Driver as the connection type to tell it you want to use the IBM DB2 JDBC driver. Then enter the database JDBC name, jdbc:db2:CMPS. Your screen should now look like Figure 84, click OK.

Developing a Container-managed persistence bean

149

Figure 84. Database Connection Info Window VisualAge for Java

4. You need to select the tables from which you want to import into. Select the CMPS then click the Build table list. You should see your CUSTOMER table in the tables list as in Figure 85. 5. Select the CUSTOMER table and click OK. The Qualifier corresponds to the schema name defined in your DB2 database.

150

Developing Enterprise JavaBeans with VisualAge for Java

Figure 85. Select Tables Window

6. The Schema Browser now has one table added to the Customer schema, the CUSTOMER table. If you select the Customer Schema and then the CUSTOMER table, you will see the different columns in the columns list, see Figure 86.

Figure 86. Schema Browser

Developing a Container-managed persistence bean

151

We need to change the default type converter for all Char fields to VapTrimStringConverter. If VapTrimStringConverter is not used and the default VapConverter is used with database mappings of specific lengths then there will be persistence problems. 7. Select CUSTOMER from the Tables list. Double-click on the CUSTID column to open its definition. This brings the column editor. A data type conversion must be applied between DB2 and Java types. This is the role of Converters. 8. Select VapTrimStringConverter as the converter in the Type details group. This converter performs the correct transformation between VARCHAR and other string* to java.lang.String objects with leading and trailing blanks deleted. Your window should look like Figure 87. Click OK. Repeat this process for the FNAME and LNAME columns.

Figure 87. Column Editor

9. Select Schemas - Save Schema.... Choose the ITSO Bank project and the itso.samples.ejb.CMP package. Click Finish. This create a new class named <schemaName>Schema with a single static method

152

Developing Enterprise JavaBeans with VisualAge for Java

infoString() containing information gathered by the Schema browser (see Figure 88).

Figure 88. CustomerSchema class Created After Saving the Schema

10.Exit the schema browser by closing the window.

Defining a map between the EJBs and the database schema


Once your schema is created, you need to define a mapping between the schema and your enterprise Beans fields. VisualAge for Java uses the schema mapping to generate the SQL code necessary for create, read, update and delete operations on the database columns for your CMP bean. From the window menu, select EJBs->Open To->Schema Maps to open the Map Browser illustrated in Figure 89.

Developing a Container-managed persistence bean

153

Figure 89. Map Browser Window

To create a new map for your Customer schema, you need to: 1. Click the mouse button 2 in the Datastore Maps list then select New EJB Group Map from the pop-up menu. (The choice New datastore Map... should not appear when working with EJBs. In this version of VisualAge for Java only the Persistent Builder knows about models.) VisualAge for Java displays the New Datastore Map. 2. Enter CMPS for the map name, this is the name VisualAge for Java will use to save the map defined. Select ITSOEJBGroup from the EJB Group choice list and the Customer schema, which we created previously. Your window should look like Figure 90. Be sure you selected the proper EJB Group and Schema because we are not able to change them after. Click OK.

154

Developing Enterprise JavaBeans with VisualAge for Java

Figure 90. New Datastore Map

3. VisualAge for Java displays the newly created CMPS Datastore map in the map browser with its associated persistent class Customer. 4. A table map define the links between your EJBs and database tables. To create a new table map, click the mouse button 2 in the Table Maps list then select New Table Map - Add Table Map with no inheritance. Choose the CUSTOMER table from the combo-box (this CUSTOMER table is coming from the table associated with the Customer Database Schema) and click OK. Your screen should now look like Figure 91.

Figure 91. Map Browser Window with Customer Table Map

Developing a Container-managed persistence bean

155

5. For this table map, you now need to define a property map. With this property map you tell VisualAge for Java what are the database fields the member fields of your EJB map to. Select the CUSTOMER Table Map, since we need to define its properties. Click the mouse button 2 on it and select Edit Property Maps. You see a window like Figure 92.

Figure 92. Property Map Editor

6. The Property Map Editor lets you define, for each of your beans members, what is the corresponding field in the database. The Class Attribute column lists all of the CMP fields of your Enterprise bean. The Table Column lists the fields from the database table. From the Map Type column you can choose 3 values: Simple: the simple mapping type is used to map one member field to one table column. We use this type in our Customer example. Complex: the complex mapping type is used when you need to map one member field to multiple database columns. The complex mapping is described in "Using Composers" from the EJB Development Environment documentation which comes with the Enterprise Update of VisualAge for Java. Not Mapped: no mapping has been defined yet for your field. Select the values according to what is shown in the Figure 93 and click OK. You have now a map defined for the CUSTOMER table.

156

Developing Enterprise JavaBeans with VisualAge for Java

Figure 93. Customer Property Map Editor Window.

7. Select the CMPS Datastore map. Select Datastore Maps - Save Datastore Map from the menu. Choose the ITSO Bank project and the itso.samples.ejb.CMP package. Be sure you selected the proper EJB Group and Schema because we are not able to change them after. Click Finish. This create a new class named <mapName>Map with a single static method infoString() containing information gathered by the Map browser (see Figure 94).

Figure 94. CMPSMap class Created After Saving the Map

Developing a Container-managed persistence bean

157

8. Exit the schema browser by closing the window.

4.7 Adjusting the deployment descriptor attributes


Since you need to define the deployment descriptor for the Customer Bean you can do this by selecting the Bean and then selecting the Properties item from the EJB menu. In the EJB Workspace: 1. Go to the EJBs list. 2. Select ITSOEJBGroup. 3. Select CustomerBean class. 4. From the menu, select EJBs->Properties. The Properties window appears:

Figure 95. Properties Window

158

Developing Enterprise JavaBeans with VisualAge for Java

In the Bean page you can specify the following: In the Enter the JNDI name for BeanHome field, type the JNDI name to associate with the EJB in the JNDI name space. The container binds the EJB's home interface with a JNDI name that includes the name you specified. The name you specify in this field is the name that your client code provides when invoking a lookup on the initial naming context. In the Transaction Attribute drop-down box, select a transaction attribute. This attribute tells the container how to manage transaction scopes before and after the execution of the EJB method. We keep the default, TX_REQUIRED. The different transaction attributes are described in the Chapter 7, Transactions on page 211. In the Isolation Level drop-down box, select an isolation level. This level tells the container what isolation level to set on the database connections used by the EJB at the start of each transaction. Actually, WebSphere ignores this isolation level. The Chapter 7, Transactions on page 211 covers this. In the Run-As Mode drop-down box, select a run-as mode. This selection tells the container the security identity to associate with the execution of the EJB method. To learn more about security, see Chapter 8, Security on page 235. Reentrant, By default, an entity Bean instance is not re-entrant. If an instance executes a client request in a given transaction context, and another request with the same transaction context arrives at the EJB object, the container throws the java.rmi.RemoteException to the second request. This rules allows the Bean developer to program the Bean as single-threaded, non-reentrant code. Re-entrant Beans must be programmed and used with great caution. First, the Bean programmer must code the Bean with the anticipation of a loopback call. Second, since the container cannot, in general, tell a loopback from a concurrent call from a different client, the client programmer must be careful to avoid code that could lead to concurrent call in the same transaction context. Concurrent calls in the same transaction context targeted at the same EJB object are illegal, and may lead to unpredictable results. Since the container cannot, in general, distinguish between an illegal concurrent call and a legal loopback, application programmers are encouraged to avoid using loopbacks. Entity Beans that do not need callbacks can be marked as non-reentrant in the deployment descriptor, allowing the container to detect and prevent illegal concurrent calls from clients.

Developing a Container-managed persistence bean

159

The Environment and Method pages are explained in Chapter 3, Developing a session enterprise bean on page 19. We are now ready to generate the deployment code for the Bean:

4.8 Generating your deployed code


Before deploying your EJBs you need to generated the deployed code. 1. Select your Customer Bean from the EJBs list. 2. Click on the mouse button 2, select Generate - Deployed code from the popup menu. Wait until the code generation is completed. VisualAge for Java generates all the stubs, skeletons, helper and holder classes which are needed by the RMI-IIOP communication layer. VisualAge for Java generates the finder and persister classes needed by the container for the deployment of your CMP Entity beans. We use the generated EJSJDBCPersisterCustomerBean to help us creating the needed SQL Query string needed by the special finder method as described in the topic 4.9, Adding Special Finder methods on page 160. VisualAge for Java comes with a test client facility to help you with the testing of your EJBs. To generate the test client for your Customer entity bean: 1. Select your Customer Bean from the EJBs list. 2. Click on the mouse button 2, select Generate - Test Client from the popup menu. Wait until the code generation is completed.

4.9 Adding Special Finder methods


A special finder method is a finder method different from the findByPrimaryKey. VisualAge for Java generates all the SQL code necessary to query the database for your special finder methods. To create a finder method to query the Customer Bean on its lastName field, we need to do 2 things: 1. Insert a finder method declaration in the CustomerHome interface. 2. Create a query string in the CustomerFinderHelper interface.

160

Developing Enterprise JavaBeans with VisualAge for Java

Insert a finder method declaration in the CustomerHome interface


Since we generated the deployed code, VisualAge for Java displays all the generated methods in the Types list. To hide the deployed generated methods. Click on the Show Generated Types icon which is beside the Field icon in Types list header. We want to add a finder method querying the Customer bean on its lastName field. To add the declaration of this finder in the CustomerHome interface: 1. Select the CustomerHome interface from the Types list. 2. Inside the Methods Add->Method.... pane, click mouse button 2 and select

3. In the Create Method smart guide, enter the following declaration in the text field: public java.util.Enumeration findByLastName(java.lang.String param) and press Next. 4. From the Attributes window press Add... button. In the Exceptions window, in the Pattern (# = any character, * = any string) text field enter RemoteException, select it from the Type Names list and click Add. Repeat the same actions but in the Pattern (# = any character, * = any string) text field enter FinderException select it from the Type Names list, click Add and Close buttons. This takes you back to the Attributes window where you can check that java.rmi.RemoteException and javax.ejb.FinderException have been added. Press Finish. 5. Save your changes. 6. The findByLastName(String) method appears in the Methods list of the CustomerHome interface.

Create a query string in the CustomerFinderHelper interface


We want a finder method to query the Customer Bean on its lastName field. For the finder declaration we defined in the CustomerHome interface, we need to insert a corresponding query string in the CustomerBeanFinderHelper interface. The query string must specify the correct table name and the correct column names in the correct order. The easiest way to do this is to copy and modify the generated select statement from the persister class. The persister class for the Customer bean is named EJSJDBCPersisterCustomer. The EJSJDBCPersisterCustomer

Developing a Container-managed persistence bean

161

class contain a static String constant called findByKeySqlString. Construct your query string by copying this select statement and modifying the where clause. 1. To show the deployed generated methods. Click on the Show Generated Types icon which is beside the Field icon in Types list header. The list of generated classes appear and you can see that three classes (_CutsomerHomeSkeleton, _CustomerHomeStub and EJSCustomerHome) are marked with a cross indicating an error due to the addition of a new method in the home interface. Do not worry, the next generation of deployment code done by VisualAge for Java will fix these errors. 2. Select the EJSJDBCPersisterCustomerBean from the Types list. 3. Find the findByKeySqlString static member from the EJSJDBCPersisterCustomerBean class. Copy the SQL Select statement. 4. To hide the deployed generated methods. Click on the Show Generated Types icon which is beside the Field icon in Types list header. 5. Select the CustomerBeanFinderHelper interface from the Types list. 6. In the Source pane, paste the SQL statement from the clipboard inside the body of the method, change the method name to findByLastName:
public static final String findByLastName = "SELECT T1.CUSTID, T1.FNAME, T1.LNAME FROM CMPS.CUSTOMER T1 WHERE (T1.CUSTID = ?) AND (T1.LASTNAME = ?) ";

7. Modify the where clause from the SQL String. We want a filter on the LASTNAME only. You code should look like:
public static final String findByLastName = "SELECT T1.CUSTID, T1.FNAME, T1.LNAME FROM CMPS.CUSTOMER T1 WHERE T1.LASTNAME = ? ";

8. Save your interface. 9. Select the Customer EJB in the EJBs list and click the mouse button 2. Select Generate - Deployed code. If you recreate a Schema map later, you will first have to regenerate the code and then copy the query string from the EJSJDBCPersisterYourBeanName class. The query string is referenced by the finder implementation class generated by the deployment tool. You need to follow a few guidelines when you create special finder methods. The name part of nameQueryString must be the name of the method.

162

Developing Enterprise JavaBeans with VisualAge for Java

The number of question marks in your nameQueryString must match the number of parameters in the Finder method. When you later generate the deployment classes, the question marks in the nameQueryString are automatically replaced with the parameters defined in the Finder method. If you use the top-down approach for creating your database schemas and maps, you will not find the findByKeySqlString static member, you have to look for the loadString static member in your EJSJDBCPersisteryourName class. Copy and modify the SQL select from this member.

4.10 Testing your Bean


To test our Customer entity bean, we need two things: 1. the generated deployed code. 2. the generated test client. We already generated these classes. To run the test client, you need to go in the server configuration window: 1. Select the Customer bean in the EJBs list. 2. Select EJBs - Open To - Server Configuration from the menu. 3. Start the Location Service Daemon. 4. Start the Persistent Name Server. 5. Select the EJB Server (server1) from the Servers list. Click on the mouse button 2 and select Start server. 6. Switch to the VisualAge for Java Console to check if your server is started.

Developing a Container-managed persistence bean

163

Figure 96. Checking Your Server is Ready

7. Go back to the EJB Server Configuration window. In the EJBs pane expand ITSOEJBGroup by clicking on the "+" sign beside the ITSOEJBGroup (see Figure 97).

164

Developing Enterprise JavaBeans with VisualAge for Java

Figure 97. Running the Test Client

8. Select the Customer EJB. Click mouse button 2 and select Run Test Client. You can also select Customer and click on the yellow icon . Wait to see a window like Figure 98.

Developing a Container-managed persistence bean

165

Figure 98. Customer EJB Test Client

9. Click on Connect. VisualAge for Java tries to locate the Customer EJB using the JNDI. When the object is located, VisualAge for Java displays the home interface of the Customer EJB, see Figure 99.

166

Developing Enterprise JavaBeans with VisualAge for Java

Figure 99. Customer Home Interface

10.We want to find the Customer with the id equals to "104 " and which last name is "Picon". Click on the findByPrimaryKey(CustomerKey) from the Methods list. 11. We need to create the CustomerKey object to pass as parameter. Click on New....To know how to create the CustomerKey, refer to the Figure 100. Select the new CustomerKey(String, String) constructor, since we need to specify the key members value. Enter 104 as the parameter[0] value and Picon as the parameter[1] value. Click Send and Done.

Developing a Container-managed persistence bean

167

Figure 100. CustomerKey Creation

12.You are now back to the Customer home interface. Click on the Send button to execute the findByPrimaryKey. After a while, VisualAge for Java returns to you with the remote interface of the Customer EJB, see Figure 101.

Figure 101. Customer Remote Interface

168

Developing Enterprise JavaBeans with VisualAge for Java

13.Select the getFirstName() method then click the Send button. VisualAge for Java returns to you with the first name of the Customer EJB previously returned by the findByPrimaryKey, see Figure 102.

Figure 102. Customer getName() Output

14.We now want to add a new instance of Customer EJB. From the top of the test client Customer window, select in the Page combo box Home interface. Click on the Create(CustomerKey) method click on New.... Select the new CustomerKey(String, String) constructor and enter 999 in the [0] (String) parameter text field as the first parameter value and Dessureault in the [1] (String) text field as the second parameter value. Click Send and Done.

Developing a Container-managed persistence bean

169

Figure 103. New CustomerKey Value

15.Click the Send button from the home interface. 16.The test client does not allow you to work with the newly created instance. So, you need to Exit and restart the Test client again. 17.After the TEst client is opened, press Connect. 18.In the Methods list of the Remote interface select the findByLastName(String) method enter Dessureault as the parameter value and click on the Send button see Figure 104.

170

Developing Enterprise JavaBeans with VisualAge for Java

Figure 104. Retrieve Dessureault Customer instance Using FindByLastName

19.The Test client Customer VisualAge for Java returns to the Remote Interface and an enumeration containing our Customer bean. You can now select getLastName() method and press Send. As a result you see (String) Dessureault. 20.Click on the Exit button to quit the Test client. Go to the EJB Server Configuration window and stop the Location Service Daemon, the Persistent Name Server and the EJB Server (server1).

Developing a Container-managed persistence bean

171

172

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document version 1.0 *IBM Confidential*

5 Developing a Bean-managed persistence bean


In this chapter you will learn how to build a Entity Bean with self-managed persistence.

5.1 Bean-managed persistence Entity bean


Bean-managed persistence (BMP) implies that the task of persisting the entity is performed by the bean itself. This contrasts against the Container-managed persistence where the container generates the persistence code for a deployed entity bean. BMP has the advantage of having a greater degree of granularity but has the disadvantage of being targetted for onle a single type of data store and hence a loss of reuse. The Bean developer has to develop the business logic as well as the logic to persist the bean to a data store.

Copyright IBM Corp. 1999

173

You may decide to go in for this approach in the following situations:


u If the persistence store for the bean is a legacy application, a proprietary

data store or a database which uses non-standard (non-JDBC) drivers.


u If you want to use a data store which is not usually supported by

Enterprise Javabean containers. Most containers use databases as persistence store. If you prefer storage mechanisms like flat/XML files which are supported by only a few containers its best to use Bean-managed persistence.
u If you are paranoid about the code generated by the container!

5.2 The TransactionRecord Entity bean


In this chapter we will develop a BMP TransactionRecord Entity bean. The TransactionRecord represents a transaction involving a customer and a bank through his/her bank account. The TransactionRecord bean stores the following information about a particular transaction:
u transId (java.sql.Timestamp): A unique Transaction ID u accountId (java.lang.String): The Account ID of the customer u amount (java.math.BigDecimal): The amount transacted (a negative

value for a debit and a positive one for a credit).

Creating the Entity bean


Before continuing, ensure that you have added the IBM EJB Development Environment 1.0 feature to VisualAge for Java. To create the TransactionRecord bean: 1. In the EJBs pane, select an EJB group to contain your EJB and click mouse button 2.

174

Developing Enterprise JavaBeans with VisualAge for Java

2. From the pop-up menu, choose Add - EJB. The Create EJB SmartGuide appears.In the Bean name field, type in the name of the new EJB (TransactionRecord).

Figure 105. The Create EJB SmartGuide

3. From the Bean type drop-down list, select the Entity bean with Bean-managed persistence fields (BMP) item to indicate that the bean is a BMP entity.

Developing a Bean-managed persistence bean

175

4. In the Project field, type the project name, modify the default name, or click the Browse button and select the project that contains (or will contain) the EJB bean class from the list of projects, then click OK. By default, the project to which the EJB group belongs is displayed. 5. Click on Finish to create the bean. The names for the EJB home interface, remote interface, and key class (for entity EJBs only) will serve as the default names.

Adding and defining BMP fields


When you create an EJB in the EJB Development Environment, certain fields are created automatically in the bean class. This topic explains how to add the bean specific fields to the TransactionRecord EJB, namely:
u transId (java.sql.Timestamp) u amount (java.math.BigDecimal) u accountId (java.lang.String)

These fields are declared as public and are accessible via public getter methods. To add a field to the TransactionRecord bean: 1. In the Types pane of the EJB page, select the TransactionRecord bean class.

176

Developing Enterprise JavaBeans with VisualAge for Java

2. Click on the Add Field button to launch the Create Field SmartGuide.

Figure 106. The Create Field SmartGuide

3. Fill in the field name, type name and select the Access with getter and setter methods. 4. Select the public radio button for Getter and private for Setter. 5. Click Finish to generate the field.

Understanding the Generated Methods


When you create an EJB in the EJB Development Environment, a set of methods for the bean is automatically created. If you select the

Developing a Bean-managed persistence bean

177

TransactionRecord bean in the EJBs pane, the Java methods of the bean implementation class are displayed in the methods pane.

Figure 107. The Generated Methods and Classes

VisualAge for Java automatically creates the following methods, in addition to the getter and setter methods for the fields we defined, for a BMP entity bean:
u public void ejbActivate();

This life-cycle call-back method of the entity bean is invoked when the container assigns an instance from the pool to a specific EJB object identity. This signals the ready state for the enterprise bean. You can use this method to load additional resources in the bean.
u public TransactionRecordKey ejbCreate(TransactionRecordKey key);

VisualAge for Java generates a default ejbCreate(...) method which takes the EJB Key class, TransactionRecordKey, as a parameter. This signature matches the create(...) method of the beans home interface. You should use this method to: Validate the passed arguments Initialize the instances variables

178

Developing Enterprise JavaBeans with VisualAge for Java

Create an entry representing the entity in the persistence store Finally, you should return the primary key for the entity at the end of this method.
u public

TransactionRecordKey (TransactionRecordKey key);

ejbFindByPrimaryKey

VisualAge for Java creates this default finder method which uses a TransactionRecordKey object to identify a particular entity. You should do the following: Validate the client-passed arguments Locate the entity in the persistence store Refresh the state of the instance from the state in the persistence store Return the primary key at the end of the method
u public void ejbLoad();

This life-cycle call-back method is invoked on an instance in order to refresh its state. You should implement the logic to read the entity state from the persistent store and synchronize the instance variables accordingly.
u public void ejbPassivate();

The EJB container invokes this method when it decides to send the instance to the pooled state. In the pooled state, the instance is disassociated from its EJB Object identity. You can use this method to release any resources that were allocated in the ejbActivate() method.
u public void setEntityContext(EntityContext ctx);

The EJB container uses this method to pass a EntityContext reference to the Entity bean. VisualAge for Java generates the code for storing the entity context in an instance variable.
u public void ejbPostCreate(TransactionRecordKey key);

This life-cycle call back method indicates that the EJB Object identity is available. For each ejbCreate(...) method, there is a matching ejbPostCreate(...) method with the same input parameters.
u public void ejbRemove();

This method is invoked by the container when the client invokes the remove method. This ends the life of an EJB object. You should implement the logic to remove the entity from the persistence store.
u public void ejbStore();

The container invokes this method on the instance when it decides to synchronize the instances state in the persistence store with the

Developing a Bean-managed persistence bean

179

current state. You should implement the logic to update the instances state in the persistence store.
u public void unsetEntityContext(EntityContext ctx);

The container invokes this method when it wants to reduce the size of the instance pool.

Modifying the Key Class


The TransactionRecordKey class generated by VisualAge for Java uses a String field to represent the primary key. Change this fields type to java.sql.Timestamp to match the transId field in the TransactionRecord bean. This will also involve modifying the constructor of this class to accept a Timestamp object as a parameter. It is always advantageous to use a key class that wraps the actual primary key field because if you later change the primary key field for the bean class you will not have to regenerate the home and remote methods.

Adding Remote Methods


The remote interface describes the entity beans business methods which are accessible by a client. In this section we will add four methods to the remote interface, namely:
u public java.sql.Timestamp getTransId();

Returns the transaction ID for the TransactionRecord.


u public String getAccountId();

Returns the account ID of the customer of the transaction.


u public java.math.BigDecimal getAmount();

Returns the amount transacted in the transaction. The amount may be negative if the transaction is a credit, positive for a debit and zero for a checking operation.
u public String getTransType();

Returns the type of transaction- "debit", "credit" or "checking" depending on the amount transacted.

Modifying and Adding Home Methods


VisualAge for Java creates two home methods for the TransactionRecord bean:

180

Developing Enterprise JavaBeans with VisualAge for Java

u A create(...) method which takes the key as input u A findByPrimaryKey(...) method which takes the key as input

In this section, we will modify the create method to accept the customers account ID and the amount transacted. 1. Select the ejbCreate(...) method in the Methods pane of the EJB page. The source of this method is displayed in the Source pane. 2. Modify the method in the Source pane as below: Alter the argument list of the method to include a BigDecimal argument (to pass the amount) and a String argument (to pass the account ID). Perform any validation or null-check on the passed arguments in the body of the method. Set the amount and accountId fields of the bean to the respective arguments. Set the transId to the a Timestamp representing the current time. Return a TransactionRecordKey wrapping the transId. 3. Save the changes. 4. Add the method to the beans home interface. Next, we add a finder method (ejbFindTransactionSummary) to the TransactionRecord bean which returns an enumeration of the last 10 transactions made by a particular customer. 1. Select TransactionRecord in the Types pane. 2. Click on the Add method button. This launches the Create Method SmartGuide. 3. Specify the signature for the new public method: Set the name of the method as ejbFindTransactionSummary Set the return type as java.util.Enumeration Specify a String input argument, accountId, which identifies the customer. Specify the exceptions that this method may javax.ejb.FinderException and java.rmi.RemoteException. throw:

4. Click on the Finish button in the Create Method SmartGuide to generate the method. 5. Add the method to the beans home interface.

Developing a Bean-managed persistence bean

181

We have not as yet provided any logic to manage the persistence store as yet. In the remaining portion of the chapter we describe how an entity bean can persist itself to an XML file. We start with a brief introduction to XML and developing XML based applications with java. You can skip these portions if you know them already and directly go to Chapter 5.4, Persisting to an XML File on page 183.

5.3 XML - The eXtensible Markup Language


Introduction to XML
Extensible Markup Language (XML) is a framework for defining document markup languages. In simple terms, a document markup language is a set of elements (frequently called tags) that have one or more of the following functions:
u Describe the structure of the document u Describe the content of the document u Control how the document is presented to the user

HTML is the most widely used markup language for Web-based documents. As the popularity of HTML increases, the limitations of the language have become more apparent. Those limitations include restricting the user to a relatively small set of tags. HTML authors cannot create their own HTML tags, because commercially available Web browsers have no knowledge of tags that are not part of the HTML standards that the browsers support. In the XML document, the tag names convey the meaning of the data they contain. The structure of the document is easily discerned and follows a pattern. In contrast, the HTML tag names reveal little about the meaning of their content and the structure is not particularly useful for manipulating the document and exchanging it between applications.

The Document Object Model- DOM


You can easily create, navigate, manipulate and modify XML documents in your java applications by using the XML4J parser which is included in the EJB Development feature of VisualAge for Java. The parser includes the Document Object Model (DOM) API for document operations. DOM is a language-independent API for XML and HTML documents. The API represents XML and HTML documents as objects that can be accessed

182

Developing Enterprise JavaBeans with VisualAge for Java

by object-oriented programs (such as Web browsers, document search engines, conversion tools, business logic, and scripting languages). By using the DOM, these programs can create, navigate, manipulate, and modify the documents. The DOM can be used to represent an existing XML document or generate an XML document. The document is stored in computer memory. In the DOM, a document consists of a collection of Nodes that have parent/child relationships. The Node is the primary object and can be of different types (such as, Document, Element, Attribute, Text, Processing Instruction, CDATA Section, and Comment). The DOM Java classes are included in the XML4J parser. Point your browser to http://www.alphaWorks.ibm.com/formula/XML to download the XML4J documentation and http://www.w3c.org/DOM/ to learn more about DOM.

5.4 Persisting to an XML File


You should consider using XML as a persistence store when you expect a large set of low use data, like logs of user interactions. Storing such information in a database may be an overkill because the data is used rather infrequently. XML provides a very simple storage option without the use of any database. You will, however, have to implement the beans persistence and the logic to handle concurrent access yourself. An Entity bean represents content in a XML Document. In the XML context for a document of information, there is one bean for each child element of the documents root element. The bean acts upon the XML file using its DOM. For every entity bean there is a node in the DOM which represents the element in the XML file.

Developing a Bean-managed persistence bean

183

Figure 108. Mapping Entity Beans to an XML File

Figure 108 illustrates the mapping between the Entity bean and the XML file. Every instance of the TransactionRecord bean corresponds to a unique transaction element. All the transaction elements are nested within a root document element named transactionDB. The attribute transId and the sub-elements, amount and accountId, within the transaction element represent the fields of the TransactionRecord bean. The choice of XML as the persistence store for the bean stems from the fact that the number of TransactionRecords will be large and that this data will be used infrequently as it is only reference data. Now we will illustrate the steps involved in creating the XML file to store the Entity beans instances.

Organizing the XML file


The first step involved in persisting the TransactionRecord Entity bean to a XML file is to create its structure. This involves describing the following:
u the hierarchy of elements u the attributes of its elements u mapping between the fields of the bean and content/markup

184

Developing Enterprise JavaBeans with VisualAge for Java

The map is in the form of a Document Type Definition (DTD). The DTD represents the metadata of the XML file. Creating the Document Type Definition is not important but it will help describe the mapping process between the Entity bean (TransactionRecord) and the XML file.

String accountId BigDecimal amount Timestamp transId

<!DOCTYPE transactionDB [ <!ELEMENT transactionDB (transaction)*> <!ELEMENT transaction (amount, accountId)> <!ATTLIST transaction transId ID #REQUIRED> <!ELEMENT amount (#PCDATA)> <!ATTLIST amount class CDATA "java.math.BigDecimal"> <!ELEMENT accountId (#PCDATA)> <!ATTLIST accountId class CDATA "java.lang.String"> ]>

Transaction Record

Document Type Definition

Figure 109. Document Type Definition (DTD) for the TransactionRecord

The DTD describes the hierarchy of the elements that will exist in the XML file. It has a root element transactionDB. Nested within the transactionDB element are zero or more transaction elements. Every instance of the TransactionRecord bean is represented as a transaction element. The transaction element has an attribute transId and two sub-elements, amount and accountId. The fields of the TransactionRecord are mapped as follows
u The transId field is represented as an ID attribute of the transaction

element
u The amount field is stored as text within an amount element which is a

child of the transaction element


u The accountId field is stored as text within an accountId element which

is a child of the transaction element You could alternatively map the transId field as text within a sub-element like the other fields. We use the earlier approach due to the inherent benefit of using an ID attribute in an XML file- it does not allow duplicate attributes.

Developing a Bean-managed persistence bean

185

Accessing the DOM

transactionDB

transaction transId 1999-02..

transaction

amount

accountId

666.6

SL2447

Figure 110. The Document Object Model

The figure shows the DOM for a TransactionRecord Log. The Element node (folder) is the root of the tree. Each of the Element nodes (transactionDB, transaction, amount and accountId) is a tag in the document. The text (data) within each tag is a Text node, represented in the figure as rectangular nodes. Attribute nodes (dashed ovals) represent attributes within tags, like the transId of the transaction. Listed below is a summary of the DOM operations. You can refer to w3cs DOM specification to get more information about the interfaces to access the DOM objects. All the classes used in the descriptions below have the package name org.w3c.dom unless explicitly stated.

186

Developing Enterprise JavaBeans with VisualAge for Java

Table 2. Creating the Different DOM Nodes in the hierarchy


A DOM Document Root element transactionDB for the Document A transaction element transactionDB element within the Document doc = new com.ibm.xml.parser.TXDocument(); Element root = doc.createElement("transactionDB"); doc.appendChild(root); Element transElement doc.createElement("transaction"); root.appendChild(transElement); transElement.setAttribute("transId", "1999-02-...") Element amountElement = doc.createElement("amount"); transElement.appendChild(amountElem ent); amountElement.appendChild( doc.createTextNode("666.6")); =

A transId Attribute for the transaction element An amount Node for the transaction element

Setting the amount data, 666.6, for the amount node

The accountId node can be created just like the amount node. The creation of the DTD has not been described because there is no standard API for constructing the DTD nodes. Moreover, the DTD only validates the XML document which is enforced by the Persister class.

Developing a Bean-managed persistence bean

187

Table 3. Accessing the Different DOM Nodes


The DOM Document "file:/e:/ejb/Log.xml" for the file Document doc = new com.ibm.xml.parser.Parser("..").readStrea m(new java.io.FileInputStream ("file:/e:/ejb/Log.xml")) Element root = doc.getRootElement() NodeList nl=root.getElementsByTagName("transac tion") for (int i = 0; i < nl.getLength(); i+) { Element transEl = (Element) nl.item(i); if (transEl.getAttribute("transId").equals("19 99-02-...")) { // this is the node we are looking for } transElement.getAttribute("transId") Element amountElement = (Element) transElement.getElementsByTagName(" amount").item(0) String amount = ((Text) amountElement.getFirstChild()).getData (); transElement.getParentNode().remove Child(transElement); ((com.ibm.xml.parser.TXDocument) doc).print(new java.io.PrintWriter(new java.io.FileOutputStream("file:/e:/ejb/Lo g.xml"));

Root element transactionDB The transaction element whose transId is 1999-02-...

The transId Attribute of the element The amount Node of the transaction element The amount data of the amount node

Removing a transaction element from the hierarchy Saving the DOM "file:/e:/ejb/Log.xml" to a file,

Creating the Persister Class


We now need to persist the Entity beans instances to an XML file. To accomplish this we define a helper class, TransactionRecordXMLPersister, to manage the beans persistence. The Persistence class reads and writes an entity beans state from the XML document described in the earlier section. The Persister class is designed as a Singleton class to allow all the instances of the Entity bean to use the same XML document.

188

Developing Enterprise JavaBeans with VisualAge for Java

Fields
The TransactionRecordXMLPersister class contains the following significant fields:
u public String xmlLocation;

Contains the location of the XML file. This is initially null and is set to a location specified as an environment property in the deployment descriptor of the TransactionRecord bean.
u private static TransactionRecordXMLPersister persister;

The singleton TransactionRecordXMLPersister object.


u private Document xmlDocument;

The Document node of the XML files Document Object Model. Each entity bean is contained as a unique node within the document element.

Methods
In keeping with the Singleton design pattern which the Persister class uses, we define a private no-arg constructor for the class and a public static method, getPersister() , which returns the singleton persister object. We need to define the following book-keeping methods for this class:
u private void loadDocument();

This method loads the XML file specified by xmlLocation into the Document Object Model. If the specified file does not exist a new XML file is created using the XML4J parser API.
u private void saveDocument();

Saves the DOM Document, xmlDocument, into the file specified by xmlLocation.

The Persister class addresses the different stages of the Entity beans lifecycle:
u Creation-

An Instance of the Entity bean is created when its ejbCreate(...) method is invoked via its home interface. Within this method the Enitity bean initializes the fields and invokes the create method on the Persister, passing itself as an argument. The Persister then creates a sub-tree representing the state of the Entity and appends the root element of the sub-tree to the document element.
u Updation-

Developing a Bean-managed persistence bean

189

The state of the Entity bean is updated in the XML file when the container invokes the ejbStore() method on it. Within this method, the Entity bean invokes the update method on the XML file passing itself as an argument. The Persister searches for the element corresponding to the primary key of the passed Entity bean and updates the sub-tree accordingly.
u Refreshal-

The state of the Entity bean is refreshed when the container invokes the ejbLoad() method on the bean. In this method, the Entity bean invokes the refresh method on the Persister, passing itself and a primary key field as arguments. The Persister searches for the element containing the primary key field and updates the fields of the passed bean from the sub-tree of the element.
u Deletion-

The instance of a Entity bean is destroyed when its ejbRemove() method is invoked via its home interface. Within this method, the Entity bean invokes the remove method on the Persister, passing itself as an argument. The Persister searches for the element specified by the primary key field of the passes entity bean and deletes this node from its parent. We include an additional method in the Persister class, getTransactionSummary, which returns an enumeration of IDs of the last 10 transactions made by a particular customer. The Persister traverses through all the transaction elements and checks if the accountId of the transaction matches the customers account ID. The xmlLocation field is set in the setEntityContext(...) method of the TransactionRecord bean. Its value is specified by the value of the transaction.file property in the contexts environment.

5.5 Optimizing the Bean


The container invokes the ejbLoad() and ejbStore() method on the entity bean before and after every transaction on the bean. This is done inorder to keep the state of the entity bean in sync with its state in the persistence store. This leads to reads/writes from/to the persistence store even when the beans state has not been modified. To reduce the number of reads/writes we define a private, transient, boolean field called isModified. This flag determines whether the beans state has been modified since the last write operation. Within the business logic,

190

Developing Enterprise JavaBeans with VisualAge for Java

you should set the isModified flag to true only when the beans state has been changed. Also, in the ejbLoad() and ejbStore() methods you should: 1. Check whether beans state has been modified (check if isModified is true) 2. Perform the necessary read/writes from the persistence store 3. Set the isModified flag to false Now, when a remote method is invoked on the bean, the container calls the ejbLoad and the ejbStore methods before and after the method which first checks whether a read/write to the persistence store is required. The isModified flag must be set to true in the following methods:
u ejbActivate u ejbPassivate u setEntityContext u ejbRemove u Any business method which alters the beans state

You should unset the isModified flag (set it to false) at the end of the ejbLoad, ejbStore and ejbPostCreate methods.

5.6 Specifying Environment Properties


Before you deploy the TransactionRecord bean, you should make an entry of the transaction.file property in the deployment descriptor. This property specifies the location of the XML file where the states of the bean will be saved and read from. You can set this property by following the below steps: 1. Select the TransactionRecord bean in the EJBs pane 2. Click on the Properties menu-item of the pop-up menu. This launches the Properties dialog.

Developing a Bean-managed persistence bean

191

3. In the Environment page of the Properties dialog, set transaction.file property along with the location of the XML file.

the

Figure 111. Setting an Environment Property in the Deployment Descriptor

4. Click on OK to save the changes

5.7 Transaction Management of the XML BMP


The Entity Bean, TransactionRecord, performs transaction management by itself. This Bean uses the auto-commit feature, that is, any change in the state of the bean is reflected immediately in the XML data store. Entity bean creates and removes can not be rolled back. To fit into the EJB model of having the container manage the beans transaction, the TransactionRecordXMLPersister should be made transaction-aware. The persister class should be modified to register with the executing threads current transaction and persist the beans state only on a commit. The Entity bean can not use the SessionSynchronization interface to be notified about transaction states like afterBegin, beforeCompletion and

192

Developing Enterprise JavaBeans with VisualAge for Java

afterCompletion. The EJB 1.0 Specification has restricted the usage of this interface only to Session beans and although Websphere allows its use in Entity beans this approach is non-standard and may not work on other servers.

Developing a Bean-managed persistence bean

193

194

Developing Enterprise JavaBeans with VisualAge for Java

6 Naming Services
A fundamental facility in any organized system is the means by which objects are found given their names. This is the role provided by a Naming Service. Many naming services are extended with a directory service. While a naming service allows you to look up an object given its name, a directory service also allows such objects to have attributes. Therefore, in addition to lookup, you can also get an objects attributes or search for objects given their attributes. Java Naming and Directory Interface (JNDI) is an API specified in the Java programming language that provides directory and naming functionality to Java applications. It is defined to be independent of any specific directory service implementation giving access to new and existing directories through a common way. The JNDI Service Provider Interface (SPI) provides the means by which different directories can be made accessible from application using JNDI. Figure 112 shows how the different components relate to each other.

Copyright IBM Corp. 1999

195

Figure 112. JNDI Architecture

By using the JNDI API an application can get access to an initial context. From this initial context it can navigate through a naming tree composed of sub-contexts to which are attached atomic name bound to object reference. This naming tree can represent a complexe system including:
u naming system.

It is a connected set of contexts of the same type.


u name space

It is a set of all names in a naming system.


u composite name

It is a name that spans multiple naming systems. As a result, a composite name can be made up of different parts belonging to different name spaces: DNS and a file system name space for example. The JNDI is divided into three packages:
u javax.naming

This package contains classes and interfaces for accessing naming services.
u javax.naming.directory

This package extends the javax.naming package to provide functionality for accessing directory services in addition to naming services. This package allows applications to retrieve attributes associated with objects

196

Developing Enterprise JavaBeans with VisualAge for Java

stored in the directory and to search for objects using specified attributes. WebSphere Advanced Edition 2.0 supports naming only.
u javax.naming.spi

This package provides the means by which naming/directory service providers can develop and hook up their implementations so that the corresponding services are accessible from applications that use the JNDI. From this high level view of what a JNDI implementation can support, let us see what has been made available to us in WebSphere Advanced Edition 2.0.

6.1 System view


From a system level point of view, WebSphere Advanced Edition 2.0 is limited to a configuration of a single host machine running all the Enterprise Java Server processes.

Figure 113. WebSphere Advanced Edition 2.0: System View

Naming Services

197

Even though different Enterprise JavaBeans servers could be running in different hosts, it is recommend to keep all EJB servers and the Persistent Name Server in the same host. Enterprise JavaBeans servers register EJBs with one and only one Persistent Name Server. If more than one Persistent Name Server exist in the network each one maintains an independent name space.

6.2 Naming Service Components


VisualAge for Java 2.1 is bundled with the WebSphere Advanced Edition 2.0 runtime. The JNDI implementation is based on CosNaming name service. There are 3 basics components involved:
u Location Service Daemon u Persistent Name Server u EJB Server

Location Service Daemon


Any client using JNDI connects implicitly to the Location Server Daemon after an initial context is requested. The Location Server Daemon is listening on a well known port number (9000) waiting for requests. When an object request is issued, it is forwarded to the Location Server Daemon first which retrieve the host in which the object implementation is running and return to the client ORB a new IOR pointing to the host running the EJB implementation.

Persistent Name Server


At start up, the Location Server Daemon hostname and port number are passed to the Persistent Name Server. The Persistent Name Server uses this information to inform the Location Server Daemon about its existence. The Persistent Name Server uses the native file system to maintain the naming tree information in a persistent store. A local copy is brought into memory at startup and it is this cached information that is used during resolve() or list() operations. All other actions on the naming tree are performed against the cache and the persistent store in an atomic operation.

198

Developing Enterprise JavaBeans with VisualAge for Java

EJB Server
Enterprise JavaBeans are deployed and executed in an EJB server. When started, an EJB server automatically registers EJB Home objects into the naming tree. To be able to perform this operation, an EJB server is given at startup the Location Server Daemons hostname and port number. In this way it can retrieve the naming trees root initial context and bind EJB home objects with their JNDI names into the name tree.

6.3 Using and Configuring Naming Service


When running WebSphere Advanced Edition 2.0 inside VisualAge for Java, interactions with the naming service are limited to:
u client looking for an object u changing the Persistent Name Server and EJB serverss host name for

EJB client running on a different machine.

Client looking for an object


Locating an enterprise beans home interface is a two-step process. First, you create a javax.namingInitialContext object. Then, you use the InitialContext object to get the EJBHome object. Figure 114 shows the code required to create the InitialContext object. To create this object, you construct a java.util.Properties object, assign environment values to the Properties object, and then pass the object as the argument to the InitialContext constructor.

Naming Services

199

public JpPing create() { JpPingHome pingHome = null; javax.naming.InitialContext initContext = null; // Get the initial context try { String ProviderURL = "iiop://" + EJSHostName + ":" + EJSPort; java.util.Properties properties = new java.util.Properties(); properties.put(javax.naming.Context.PROVIDER_URL, ProviderURL); // IBM name services properties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.ibm.jndi.CosNaming.CNInitialContextFactory"); initContext = new javax.naming.InitialContext(properties); } catch (javax.naming.NamingException e) { System.out.println("Error retrieving the initial context: " + e.getMessage()); } // endtry Figure 114. Creating the InitialContext Object

In ProviderURL string, EJSHostName can be set with two possible values:


u "/" indicating that the client and the EJB are located in the same machine

or
u "anyServerName.ibm.com" which is the fully qualified host name

EJSPort may take different values:


u "900" if the EJB server is running inside VisualAge for Java. This value

cannot be changed.
u "9019" if the EJB server is running inside WebSphere Advanced Edition

2.0 runtime. This value is configurable from the WebSphere Advanced Edition 2.0 Application Server Administration by selecting in the left pane WebSphere Application Server->Enterprise Java Services->Global Settings and changing the Boot Port value as shown in Figure 115.

200

Developing Enterprise JavaBeans with VisualAge for Java

Figure 115. Changing the Boot Port Value in WebSphere Advanced Edition 2.0

Once the InitialContext object is created, the application uses it to create the EJB home object, as shown in Figure 116.

Naming Services

201

// lookup the home interface using the JNDI name try { java.lang.Object o = initContext.lookup(JNDIBeanName); // this is the JNDI name if (o instanceof org.omg.CORBA.Object) pingHome = JpPingHomeHelper.narrow((org.omg.CORBA.Object) o); } catch (javax.naming.NamingException e) { System.out.println("Error retrieving the home interface: " + e.getMessage()); System.exit(0); } // endtry Figure 116. Creating the EJBHome object

This creation is accomplished by invoking the lookup method which takes the JNDI name of the enterprise bean in String form and returns a java.lang.Object object. An EJB JNDI name can be modified. You change it, inside VisualAge for Java, by opening the EJB properties and changing the value in Enter the JNDI name for BeanHome field see Figure 117.

202

Developing Enterprise JavaBeans with VisualAge for Java

Figure 117. Changing the JNDI Name under VisualAge for Java

Outside VisualAge for Java you use the WebSphere Advanced Edition 2.0s Jet tool to read the exported Jar file containing EJBs. You start the Jet tool by running drive:\WeBSphere\AppServer\sample\ejs\jet.bat command file. In the Input/Output tab, select Browse followed by the Jar file containing your EJB. According to the type of bean session or entity, the Jet tool highlights the corresponding tab. By selecting the tab, you get access to the deployment descriptor information see Figure 118.

Naming Services

203

Figure 118. Changing the JNDI Name with Jet Tool

Once you have changed the JNDI name you select Input/Output tab and enter in the Output field the path and name of a new or the same Jar file to be created or modified and then press Build button. This updates the deployment descriptor serialized file with the new JNDI name. The returned object of the lookup operation is filtered, using the static method narrow, to obtain an EJBHome object for the specified enterprise bean. The narrow method is contained in the home helper class generated during bean deployment. For the JpPing bean, this home helper class is named JpPingHelper.

204

Developing Enterprise JavaBeans with VisualAge for Java

Once a reference to the home object has been obtained, you use it to create the EJB object by using the EJB home object as shown in the following snippet of code (see Figure 119).

JpPing ping = null; try { ping = pingHome.create(); System.out.println("JpPing created!"); } catch (Exception e) { System.out.println("Exception creating new JpPing: " + e.getMessage()); } Figure 119. Creating the EJB Object

The EJB object is obtained by calling a create method or (for entity beans only) a finder method. Because the JpPing bean is a stateless session bean, the only choice is the default create method.

Changing host name to Persistent Name Server and EJB server


If you want to run an EJB client that accesses an EJB running inside VisualAge for Java but on a different machine, you need to change the LSD name value in both the Persistent Name Server and EJB server.

Naming Services

205

Figure 120. Accessing an EJB from a Different Machine

To make this change, from the workbench, select the EJBs tab, in the menu select EJBs->Open To->server Configuration as indicated in Figure 121.

Figure 121. Opening the EJB Server Configuration

This opens the EJB Server Configuration window as shown in Figure 122.

206

Developing Enterprise JavaBeans with VisualAge for Java

Figure 122. EJB Server Configuration

In the Servers pane, select Persistent Name Server click mouse 2 and select Properties. This opens the Properties for Persistent Name Server window shown in Figure 123 giving access to three parameters:

Figure 123. Persistent Name Server Properties u Initial Root

This parameter indicates where the file (root.ctx) containing the

Naming Services

207

persistent naming information is located.

Figure 124. Location for Persistent Naming Information u LSD Name

This is the host name where the Location Server Daemon is running. The LSD Name is by default set to localhost and needs to be set to the fully qualified IP host name.
u LSD Port

This is the port name on which the Location Server Daemon is listening. It must match the value defined during Location Server Daemon configuration. You also need to configure the EJB server. Follow the same steps to get access to its properties.

208

Developing Enterprise JavaBeans with VisualAge for Java

Figure 125. EJB Server Properties

Once you have changed the localhost by the fully qualified host name in the two servers, you can start all three servers: Location Server Daemon, Persistent Name Server and the EJB server. Now your client running on a different machine can get access to the EJB running inside VisualAge for Java as long as it uses the correct fully qualified name and port number (see Figure 114 on page 200).

Naming Services

209

210

Developing Enterprise JavaBeans with VisualAge for Java

7 Transactions
Nowadays, we see a lot of developpers are centralizing their business code inside objects running on a central application server. This centralization of components give more control over the application logic to these developpers. The applications developped using this kind of architecture are easier to scale as well (via things like: load balacing, database multiplexing). In the traditional procedural approach, developpers are using transactions to achieve a high degree of application integrity. A transaction is described by four properties: Atomic: transactions are all or nothing, they either work or they dont, they are never left incomplete. Consistent: transactions always let the system in a consistent state. Isolated: transactions executes in a safe manner, they will not fail if other transactions running on the same server are failing. Durable: transactions can survive system failures once they are completed and committed. The transactional application servers combine the execution of component centralized on application servers with transactionality.

Copyright IBM Corp. 1999

211

7.1 Enterprise JavaBeans & Transactions


Enterprise JavaBeans server are transactional application servers. The transactional features of the Enterprise JavaBeans (EJB) architecture provides the developer with a good transaction service. Unlike other application programming interfaces (APIs) that support distributed transactions, the EJB API does not require enterprise Bean and EJB application developers to write any special code to use transactions. Instead, the container manages transactions based on two deployment descriptor attributes associated with each enterprise Bean, and the enterprise Bean and EJB application developers are free to deal with the business logic of their applications. The Enterprise JavaBeans specifications provides the developer with some mechanisms to control the transaction processing within an Enterprise JavaBeans application. Using the Enterprise JavaBeans a developer does not face the complexity involved with the development of a transactional application. This task is left to the Enterprise JavaBeans server provider. The Enterprise JavaBeans lets a developer to update data into multiple databases, across multiple sites, if needed. All the transaction processing is handled by the Enterprise JavaBeans server. To achieve its transactionality, the Enterprise JavaBeans model implements things such as two-phase commit, transaction context propagation and distributed two-phase commit. It is up to the EJB Server vendors to decide, which technique they use. This is a simple protocol where the transaction manager first asks all participants if their work is finished and would like to attempt to commit their work. This is the first phase of the protocol. Once everyone agrees to commit, the second phase begins. For a complete definition of Two-Phase commit, refer to the following Technology Review from the Software Engineering Institute at: http://www.sei.cmu.edu/activities/str/descriptions/dtpc_body.html EJB has really the best of both worlds. If the client application developer would like to control the transactions himself (we call this: client-demarcated transactions) it is possible, see topic 7.8, Client-demarcated transactions on page 230. The EJB Container can manage the transaction processing on behalf of your EJBs as well (this is called container-demarcated transactions). This means your beans dont have to explicitly demarcate transaction boundaries. The transaction control is then handled by the EJB Server. The transaction processing applies to Session and Entity beans. Actually there is no support for nested transactions, the decision not to support nested transactions was intended to allow vendors of existing transaction processing and database management systems to incorporate support for Enterprise JavaBeans. If these vendors provide support for nested transactions in the future, Enterprise JavaBeans may be enhanced to take advantage of nested transactions.

212

Developing Enterprise JavaBeans with VisualAge for Java

The EJB Specifications describe different scenarios using transactions. We decided to illustrate the Bean-managed demarcation and the Container-managed demarcation. The client-demarcated transactions are explained in the topic 7.8, Client-demarcated transactions on page 230. We were not able to test the following scenarios, because they are not supported by the WebSphere environment: 1. the update of multiple databases via one server 2. the update of databases via multiple servers

The Bean-managed demarcation


Using the TX_BEAN_MANAGED transaction attribute, we are able to use the javax.jts.UserTransaction interface to demarcate transactions in our Session Bean. We then see what is the effect of the different transaction attributes on the Entity Beans. If your Beans are not using the TX_BEAN_MANAGED transaction attribute and they will not be allowed to control their transactions. The container will not make available the javax.jts.UserTransation to them. The javax.jts package is intended to be used both by the bean-demarcated transactions and the client-demarcated bean developer.

The Container-managed demarcation


Whenever a client invokes an enterprise Bean, the container interposes on the method invocation. The interposition allows the container to control transaction demarcation declaratively as described primarily by the methods transaction attribute and in its absence by the beans transaction attribute. Using different transaction attributes, we see how the EJBServer, WebSphere, interposes on the method invocations and control the transactions.

The Transaction attributes


The transaction attribute defines the transactional manner in which the container invokes enterprise Bean methods. This attribute can be set for the Bean as a whole and for individual methods in a Bean. The following are valid values for this attribute: TX_BEAN_MANAGEDNotifies the container that the Bean class implements the javax.jts.UserTransaction interface and that the Bean can call methods to explicitly manage transaction boundaries. TX_MANDATORYDirects the container to always invoke the Bean method within transaction context associated with the client. If the client attempts to invoke the Bean method without a transaction context, the container throws the javax.jts.TransactionRequiredException exception to the client. The transaction

Transactions

213

context is passed to any enterprise Bean objects or resources that are used by this Bean method. TX_NOT_SUPPORTEDDirects the container to invoke Bean methods without a transaction context. If a client invokes a Bean method from within a transaction context, the container suspends the association between the transaction and the current thread before invoking the method on the enterprise Bean instance. The container then resumes the suspended association when the method invocation returns. The suspended transaction context is not passed to any enterprise Bean objects or resources that are used by this Bean method. TX_REQUIRES_NEWDirects the container to always invoke the Bean method within a new transaction context, regardless of whether the client invokes the method within or without a transaction context. The transaction context is passed to any enterprise Bean objects or resources that are used by this Bean method. TX_REQUIREDDirects the container to invoke the Bean method within a transaction context. If a client invokes a Bean method from within a transaction context, the container invokes the Bean method within the client transaction context. If a client invokes a Bean method without a transaction context, the container creates a new transaction context and invokes the Bean method from within that context. The transaction context is passed to any enterprise Bean objects or resources that are used by this Bean method. TX_SUPPORTSDirects the container to invoke the Bean method within a transaction context if the client invokes the Bean method within a transaction. If the client invokes the Bean method without a transaction context, the container invokes the Bean method without a transaction context. The transaction context is passed to any enterprise Bean objects or resources that are used by this Bean method.

Transaction Isolation Levels


The transaction isolation level determines how isolated one transaction is from another for read purposes only. This attribute can be set for the Bean as a whole and for individual methods in a Bean. The following are valid values for this attribute in decreasing order of isolation: TRANSACTION_SERIALIZABLEThis level prohibits all of the following types of reads: Dirty reads, where a transaction reads a database row containing uncommitted changes from a second transaction. Nonrepeatable reads, where one transaction reads a row, a second transaction changes the same row, and the first transaction rereads the row and gets a different value.

214

Developing Enterprise JavaBeans with VisualAge for Java

Phantom reads, where one transaction reads all rows that satisfy an SQL WHERE condition, a second transaction inserts a row that also satisfies the WHERE condition, and the first transaction applies the same WHERE condition and gets the row inserted by the second transaction. TRANSACTION_REPEATABLE_READThis level prohibits dirty reads and nonrepeatable reads, but it allows phantom reads. TRANSACTION_READ_COMMITTEDThis level prohibits dirty reads, but allows nonrepeatable reads and phantom reads. TRANSACTION_READ_UNCOMMITTEDThis level allows dirty reads, nonrepeatable reads, and phantom reads. These isolation levels correspond to the isolation levels defined in the Java Database Connectivity (JDBC) java.sql.Connector interface. The container uses the transaction isolation level attribute as follows: Session Beans and entity Beans with Bean-managed persistence (BMP)For each database connection used by the Bean, the container sets the transaction isolation level at the start of each transaction. Entity Beans with container-managed persistence (CMP)The containergenerates database access that achieve the specified isolation level.ion and gets the row inserted by the second transaction. Actually WebSphere does not support these isolation levels and will, in the presence of transactions, always open a database connection with the TRANSACTION_REPEATABLE_READ isolation level.

7.2 EJB Transactions & CORBA OTS


CORBA OTS
Enterprise JavaBeans supports flat transactions, modeled after the OMG Object Trans-action Service 1.1 (OTS). The transaction model used in EJB similar to OTS. In fact, CORBA-compliant EJB servers must provide an OTS-compliant transaction service. Understanding how OTS works helps to understand how transactions work in EJB. To better understand how OTS works we need to look at its key components. The following components can be mapped almost directly to EJB, and understanding how these components work in OTS will provide a good foundation for understanding transactions in The dashed box represents a transaction. Within the transaction are all of the objectsparticipating in the transaction. Commits and rollbacks will be applied to all the Resource objects in this group.

Transactions

215

Figure 126. OTS Overview

The Control object represents the transaction. From this object we can obtain the Coordinator and the Terminator. An EJB developer never sees the Control object. It is used by the container to manage the transaction on behalf of the bean. The Terminator is also used by the container to commit or roll back the transaction when a thread returns from a bean method where the method is described in the deployment descriptor as requiring the container to terminate the transaction upon completion of the method. When a commit or rollback is requested, all the objects in the transaction will be committed or rolled back, as appropriate. The Resource is the object that has transactional state. For example, it may be a connection to a database. Calling commit() on this object would cause the database updates to be applied to the database. A rollback() would revert all changed made to the database through this connection since the start of the transaction. Once the commit or rollback completed, the corresponding rows in the database would be unlocked. The level of locking applied would have been specified in the deployment descriptor. The full set of methods for this object would show that these objects actually implement the two-phase commit protocol, allowing each object to vote as to whether the entire transaction should be committed or rolled back. The Synchronization is an object that wishes to be notified upon completion of the transaction whether the transaction was committed or rolled back. Unlike the Resource,

216

Developing Enterprise JavaBeans with VisualAge for Java

it does not participate in the two-phase commit protocol and has no vote as to whether the EJB. transaction should be committed or rolled back. It plays a passive role in the transaction. This is the role that a session bean may play by implementing a special interface. The Coordinator is the object that makes all this work. Through this object both Resource objects and Synchronization objects are registered in the transaction. The bean does not get access to this object directly. Transaction-aware objects that are intended for use with EJB will transparently obtain a reference to the current transactions Coordinator to register itself.

Transactional vs Recoverable Objects


OTS distinguishes transactional and recoverable objects. This distinction is relevant to EJB. While the full definition of these types is rather extensive in the OTS specification, it essentially means that recoverable objects have a commit() and rollback() method, allowing the transaction to directly manipulate their state or behavior. A transactional object does not have these methods, and cannot be influenced by the transaction. However, a transactional object is an object that has a transaction associated with it, so that recoverable objects (or Resources) that are allocated will be associated with the transactional objects current transaction. An enterprise bean that is transaction enabled is a good example of a transactional object. The container will maintain a transaction on behalf of the bean. Any recoverable objects that are allocated by the bean are transparently placed into the current transaction with the help of the container. The bean does not have a commit() or rollback() method, and so the transaction cannot manipulate the bean directly. It doesnt really make sense to make a bean a recoverable Resource since this would require additional work on the part of the bean developer for every bean written, and enterprise beans rarely have internal state that should directly affect the outcome of a transaction. Maybe, this is a reason why the recoverable objects are not required by the actual version of the specs. They function better as managers of recoverable objects, letting the recoverable objects do the work. Note that a bean can vote to roll back a transaction prior to the container attempting a commit or rollback.. A bean can still be told of the outcome of a transaction through the SessionSynchronization interface.

7.3 Implementing Session Synchronization


A session Bean can optionally implement the javax.ejb.SessionSynchronization interface. This interface can provide the Bean with transaction synchronization notifications in the form of container callbacks. Session Beans use these notifications to manage database data they may cache within transactions.

Transactions

217

The afterBegin notification signals a session instance that a new transaction has begun. At this point, the instance is already in the transaction and may do any database work it requires within the scope of the transaction. The beforeCompletion notification is issued when a session instances client has completed work on its current transaction but prior to committing the instances resources. This is the time when the instance should write out any database updates it has cached. The instance can cause the transaction to rollback by invoking the setRollbackOnly method on its session context. The afterCompletion notification signals that the current transaction has completed. A completion status of true indicates the transaction committed; a status of false indicates a rollback occurred. In WebSphere Advanced Edition 2.0 the entity bean implementation class can implement the SessionSynchronization interface so they can also be notified when a new transaction begins or completes. We used this in our scenario testing, since we needed to know how many transactions were involved in the test cases. Each time the afterBegin method was called in one of our Beans we printed something to the console, this way we were able to know how many transactions were started by the transaction service. Please note that we do not recommend to implement the javax.ejb.SessionSynchronization for Entity beans. This is not portable across different EJB Container vendors.

7.4 Scenarios
Scenario Description
Our design model to test the effect the transactions attributes has 4 components: one Session Bean (TransactionTest), 2 Container-managed persistence Entity Beans (CMPSample1 and CMPSample2) and one client application (SimpleClient). One scenario consist of setting the transaction attributes of the CMP Beans and run the SimpleClient Java application. The SimpleClient creates a myTransactionTest session Bean. The client application then calls 3 method on this SessionBean: test1(), test2() and test3(), see Figure 127 on page 219.

218

Developing Enterprise JavaBeans with VisualAge for Java

Figure 127. SimpleClient Application

The myTransaction.test1() and myTransaction.test2() represent our implementation of the Bean demarcated transaction model. They show the effect of the transaction attributes within the Bean demarcated transaction model. The myTransaction.test1() execute a committed transaction, see Figure 128.

Transactions

219

Figure 128. MyTransactionTest.test1() method

The myTransaction.test2() represents the rollbacked transaction, see Figure 129 on page 221.

220

Developing Enterprise JavaBeans with VisualAge for Java

Figure 129. MyTransactionTest.test2() Method

The last method the SimpleClient application calls is test3() . This method illustrates the effect of the transaction attributes within the Container-demarcated transaction model. All the transaction processing is handled by the container, see Figure 130 on page 222.

Transactions

221

Figure 130. MyTransactionTest.test3() Method

222

Developing Enterprise JavaBeans with VisualAge for Java

The implementation model


The SimpleClient object retrieves the initial context from the naming service. The initial context returns the home interface of our Session Bean, myTransactionTestHome. The SimpleClient then uses it to create our Session Bean instance, myTransactionTest. The client application then calls 3 method on this SessionBean (test1, test2 and test3).

myTransactionTest.test1()
The myTransactionTest.test1() starts by obtaining CMPSample1 home interface. The myTransaction then gets a transaction, myTransaction, from the SessionContext object. MyTransactionTest initiates the transaction with a myTransaction.begin( ) (the control of transactions from our myTransactionTest EJB forced us to specify its transaction attribute as TX_BEAN_MANAGED). Our myTransaction Bean then ask 2 values from the user: a key and a state (both strings). It creates a primary key object for CMPSample1 and tries to find using this key object. If the myTransactionTest bean does not find the CMPSample1 bean, it calls create with the key object. The CMPSample1.setState() method is called with the previously entered state as parameter. This CMPSample1.setState() method set the value of the state member of our CMPSample1 Entity Bean. Following this, the CMPSample1 Bean asks for other values (key and state) from the user and tries to find an instance of CMPSample2. If the CMPSample1 bean doesnt find it creates an instance of the CMPSample2 bean and then call the CMPSample2.setState( ) method. To complete, the myTransactionTest myTransaction.commit( ). commits the myTransaction using:

myTransaction.test2( )
The myTransaction.test2() is the second method the SimpleClient application calls. The test2() method behaves like the test1() with a few differences. The CMPSample1 Bean does not need to get the transaction object from the SessionContext, it has already be initialized in the test1() method. The myTransaction object does not commit the changes to the database, it rollbacks them with the myTransaction.rollback( ) call.

myTransaction.test3( )
The last method the SimpleClient application calls is test3(). It does the same steps as test1( ) but without the transaction related actions. The MyTranasctionTest doesnt begin a transaction. The MyTransactionTest doesnt commit nor rollback.

Transactions

223

All of the transaction processing is left to the container.

7.5 The test cases results


We present in the next tables the different results of our test cases. Each table has 3 columns: the Method called tells to what method this result refers. You can refer to the topic , Scenario Description on page 218 to have a description of this method. the Result in Database columns tells you what happened in our database after the method call completed. you find in the Comments column explanation of the result. Things like: the number of transactions involved when the transaction were started any problems encountered. The tables are presented by scenario. Here are the steps we did for each scenario: 1. we adjusted the transaction attribute of our CMP beans (CMPSample1 and CMPSample2) 2. we generated the code 3. run the SimpleClient application Following the result tables, you see an explanation of the transaction attributes according to these scenarios. We used VisualAge for Java EJB test environment with DB2 for these tests.

Result tables
For CMPSample1 and CMPSample2: Table 4. Scenario 1 - TX_REQUIRED
Method called test1( ) Result in Database Data inserted and updated in both tables No Data updated inserted or Comments Only one transaction is used during this scenario, the transaction started from the myTransactioTest session bean. Only one transaction is used during this scenario, the transaction started from the myTransactioTest session bean.

test2( )

224

Developing Enterprise JavaBeans with VisualAge for Java

Method called test3( )

Result in Database Data inserted and updated in both tables

Comments Only one transaction is used during this scenario, the transaction started by the container after the CMPSample1.setState() method call and is carried on to the CMPSample2 Bean..

For CMPSample1 and CMPSample2: Table 5. Scenario 2 - TX_MANDATORY


Method called test1( ) Result in Database Data inserted and updated in both tables Comments 3 transactions are involved. The transaction started by the myTransactionTest session Bean, one transaction is started by the container on the CMPSample1.setState and the third transaction is started by the container on the CMPSample2.setState. a 3 transactions are involved. The transaction started by the myTransactionTest session Bean, one transaction is started by the container on the CMPSample1.setState and the third transaction is started by the container on the CMPSample2.setState.b Since there is no transaction context available and the container needs one, the container throws one exception to the client when it tries to do the CMPSample1.setState().c

test2( )

No Data updated.

inserted

or

test3( )

No Data, exception on client

a. this strange results are described in the topic , Test scenarios results explanation on page 226. b. this strange results are described in the topic , Test scenarios results explanation on page 226. c. this strange results are described in the topic , Test scenarios results explanation on page 226.

Transactions

225

For CMPSample1 and CMPSample2: Table 6. Scenario 3 TX_NOT_SUPPORTED


Method called test1( ) Result in Database Data inserted in tables not updated both Comments One transaction is started by the myTransactionTest bean. The container suspends the transaction on the CMPSample1.setState() and restores it when the execution returns to the myTransactionTest bean. We have a ContainerObjectNotFoundException when we try to find the CMPSample1 bean.

test2( )

Not applicable

For CMPSample1 and CMPSample2 Table 7. Scenario 4 TX_REQUIRES_NEW


Method called test1( ) Result in Database Nothing happens, have to stop the database server. Comments Deadlock, the container CMPSample1.setState call. locks after the

For CMPSample1 and CMPSample2: Table 8. Scenario 5- TX_REQUIRED


Method called test1( ) Result in Database Nothin happens, have to stop the database server. Comments Deadlock, the container CMPSample2.setState call. locks after the

Test scenarios results explanation


Case 1: Effect of the TX_REQUIRED attribute
The TX_REQUIRED transaction attribute means that your Beans methods require a transaction in order to interact with the database system. You want to use this attribute when your beans needs to be in a transactional context to protect their integrity. Most of the time this is the transaction attribute you use with Entity Beans.

226

Developing Enterprise JavaBeans with VisualAge for Java

In the case of the presence of a transaction context, your Bean is not isolated from a clients rollback. This means if the client (either application, servlet or Bean) decides to rollback the transaction, the changes in your bean will be rollbacked as well. If no transaction is available (like in myTransactionTest.test3( )), the container will get one from the transaction service and provide it to the Bean, before any methods are invoked on it. The execution of the myTransactionTest.test3() made us realized something regarding the way our container modeled the transaction control. Our container, WebSphere Advanced Edition 2.0 forces all methods from the home to be called within a transaction context. This means all the finder and create methods will be executed transactionally. WebSphere Application Server 3.0 will make the Home interfaces EJBs, so it will be possible to describe the type of transaction attribute you need on specific finder in their deployment descriptor.

Case 2: Effect of the TX_MANDATORY attribute


A Bean with the TX_MANDATORY has to be called within the transaction context of its client (either application, servlet or Bean). If the client does not have a transaction scope, the container throws the TransactionRequired exception to the client, as we saw with the myTransactionTest.test3() method. In theory, if the calling Bean or client is associated with an existing transaction context (like in myTransaction.test1( ) and myTransaction.test2( ) methods), the container invokes Beans methods using this transaction context. This transaction context is passed to other beans when it invokes methods on it. This means if you commit or rollback the calling transaction context, all of your the work done within this transaction will be commited or rollbacked. Actually, as the results of our tests with WebSphere Advanced Edition 2.0, we saw that with WebSphere Advanced Edition 2.0 more than one transaction was started. This strange behaviour is an implementation detail of the transaction service WebSphere Advanced Edition 2.0.

Case 3: Effect of the TX_NOT_SUPPORTED attribute


The TX_NOT_SUPPORTED is for non-transactional work. Its useful if you either don't want to deal with transactions or have something that is inherently non-transactional that you effecting by the operations within the bean. Since the myTransaction transaction started by the myTransactionTest session bean is suspended when the container intercepts the CMPSample1.setState method, the update of this field is not applied in the database (it is not done within a transaction context). All of the home interface methods are forced to be executed transactionally with WebSphere, this is the reason why the record is inserted in the database.

Transactions

227

In our rollback situation method (myTransactionTest.test2()) WebSphere sent the com.ibm.ejs.container.ContainerObjectNotFoundException. This is a bug we had with WebSphere Advanced Edition 2.0.

Case 4 and case 5: Effect of the TX_REQUIRES_NEW attribute


We experienced a few problems testing those scenario. When we try to call a method on CMPSample2 from CMPSample1, the container stays into a "Wait for lock" mode, this means our bean is in a deadlock situation. We have to stop the container and database to continue working.

Case 6: Effect of the TX_SUPPORTS attribute


Actually, there is a bug in the original EntityDescriptor class which avoid us to use the TX_SUPPORTS transaction attribute. You then cannot specify this attribute with VisualAge for Java. In our case, the methods myTransactionTest.test1( ) and myTransactionTest.test2( ) both have a transaction scope when they call methods on CMPSample1. However, the myTransactionTest.test3( ) does not have a transaction context, which cause the container to raise the TransactionRequired exception to the calling SessionBean, myTransactionTest.

7.6 Concurrent access from multiple transactions


The enterprise Bean developer does not have to worry about concurrent access from multiple transactions when writing the business methods. The enterprise Bean developer writes the methods assuming that the container will ensure appropriate synchronization for entity Beans that are accessed concurrently from multiple transactions. The entity container typically uses one of two implementation strategies to achieve proper synchronization: 1. The container activates multiple instances of the enterprise Bean, one for each transaction in which the entity is being accessed. The transaction synchronization is performed automatically by the underlying database during the database access calls performed by the ejbLoad, ejbCreate, ejbStore, and ejbRemove methods. The database system provides all the necessary transaction synchronization, the container does not have to perform any synchronization logic. 2. The container acquires an exclusive lock on the instances state in the database. The container activates a single instance and serializes the access from multiple transactions to this instance. WebSphere Advanced Edition 2.0 implements a version of option 2. Only a single active instance is managed by the container. As transactions access the instance an exclusive

228

Developing Enterprise JavaBeans with VisualAge for Java

lock is placed on the active instance for the duration of the transaction. This exclusive lock avoids a common deadlock that can occur as multiple transactions access multiple beans.

Transactions

229

7.7 Transactions and Exceptions


In the case of a client-demarcated transaction which invokes an enterprise Bean business method, a create method, a remove method, or a finder method, and the method returns with an exception other than javax.jts.TransactionRolledbackException, the client can assume that the transaction has not been automatically marked for rollback. The client can assume that the transaction has been marked for rollback if the exception is javax.jts.TransactionRolledbackException. It is fruitless for the client to continue the transaction because the transaction can never commit. The client should catch the javax.jts.TransactionRolledbackException exception and stops its processing. If the client receives the java.rmi.RemoteException exception instead of the javax. jts.TransactionRolledbackException, the client, in general, does not know if the enterprise Beans method has completed or not. Therefore, if a transactional client receives the java.rmi.RemoteException exception, the client should call the rollback method on the current transaction to prevent inconsistent data. Note that an enterprise Bean who is also a client of another enterprise Bean can use the getRollbackOnly method to test if the current transaction has been marked for rollback. If the current transaction has been marked for rollback, the bean should stop its transactional processing since the transaction will be rollbacked. On the Bean side, if your Bean cannot ensure at a certain period of time that the Bean is in a consistent state, you should use the setRollbackOnly method on the EJBContext interface to mark a transaction for rollback. Then after, your Bean can throw an exception to the client. This mechanism allows you to control whether a transaction should be rolled back or not within a Bean method.

7.8 Client-demarcated transactions


The clients and Beans that have to programmatically control transaction scopes should use the javax.jts.UserTransaction interface that is defined as part of the Java Transaction Service (JTS) API. The javax.jts.UserTransaction interface is the only JTS interface that the EJB container provider must implement in order to support EJB. Java Transaction Service (JTS) API defines all the Java programming language interfaces related to transaction management on the Java platform. The EJB specification does not however define how a client application can create a transaction in that it does not specify how to obtain a reference to the javax.jts.UserTransaction interface in a client application. In the absence of this specification, the Application Server provides a class that may be used to access the JTS CosTransactions.Current interface which is a superset of the javax.jts.UserTransaction interface. This interface allows transactions to be created, suspended and resumed, and

230

Developing Enterprise JavaBeans with VisualAge for Java

committed or aborted. To obtain a reference to the org.omg.CosTransactions.Current interface, the client application may simply call the static getCurrent method on the com.ibm.ejs.client.EJClient class. For example,
org.omg.CosTransactions.Current current = com.ibm.ejs.client.EJClient.getCurrent(); current.begin(); // do transactional work current.commit(false);

Note: To ensure that the transactions created using the current interface are propagated as method invocations are made on enterprise JavaBeans, the current reference should be obtained before creating a JNDI InitialContext. For portability of client applications across different EJB implementations, developers may wish to program their clients using the javax.jts.UserTransaction interface. The following simple class implements the javax.jts.UserTransaction interface using the CosTransactions.Current interface:
package myPackage; import org.omg.CosTransactions.*; public final class UserTransaction implements javax.jts.UserTransaction { Current current = null; public UserTransaction() { current = com.ibm.ejs.client.EJClient.getCurrent(); } public void begin() throws IllegalStateException { try { current.begin(); } catch (SubtransactionsUnavailable e) { throw new IllegalStateException(e.toString()); } } public void commit() throws IllegalStateException, javax.jts.HeuristicRollbackException, SecurityException, javax.jts.TransactionRolledbackException, javax.jts.HeuristicMixedException { try { current.commit(true); } catch (org.omg.CosTransactions.NoTransaction nte) { throw new IllegalStateException("No transaction."); } catch (org.omg.CosTransactions.HeuristicMixed hme) {

Transactions

231

throw new javax.jts.HeuristicMixedException(); } catch (org.omg.CosTransactions.HeuristicHazard hze) { throw new javax.jts.HeuristicRollbackException(); } } public int getStatus() { Status stat = current.get_status(); if (stat == Status.StatusActive) return javax.jts.UserTransaction.STATUS_ACTIVE; if (stat == Status.StatusCommitted) return javax.jts.UserTransaction.STATUS_COMMITTED; if (stat == Status.StatusCommitting) return javax.jts.UserTransaction.STATUS_COMMITTING; if (stat == Status.StatusMarkedRollback) return javax.jts.UserTransaction.STATUS_MARKED_ROLLBACK; if (stat == Status.StatusNoTransaction) return javax.jts.UserTransaction.STATUS_NO_TRANSACTION; if (stat == Status.StatusPrepared) return javax.jts.UserTransaction.STATUS_PREPARED; if (stat == Status.StatusPreparing) return javax.jts.UserTransaction.STATUS_PREPARING; if (stat == Status.StatusRolledBack) return javax.jts.UserTransaction.STATUS_ROLLEDBACK; if (stat == Status.StatusRollingBack) return javax.jts.UserTransaction.STATUS_ROLLING_BACK; return javax.jts.UserTransaction.STATUS_UNKNOWN; } public void rollback() throws IllegalStateException, SecurityException { try { current.rollback(); } catch (NoTransaction nt) { throw new IllegalStateException("No Transaction."); } } public void setRollbackOnly() throws IllegalStateException { try { current.rollback_only(); } catch (NoTransaction ne) { throw new IllegalStateException("No Transaction."); } } public void setTransactionTimeout(int seconds) { current.set_timeout(seconds); } }

232

Developing Enterprise JavaBeans with VisualAge for Java

Client-demarcated transactions have disadvantages over the container-demarcated transactions. You do not control the period of time the client will use your Beans within a transaction context. This means you can waste precious server resources. For example, a client starts a transaction query an EJB, leave for the weekend. The client transaction will be active for all the weekend. Your server resources are then tied up for all this period. When you use client-demarcated transactions, you lose the flexibility to let the deployer adjust the transaction attribute as well. This means all your Beans are TX_BEAN_MANAGED and cant be tailored on depending on the deployment servers. It is generally, a good practice to specify your transactional Beans as TX_REQUIRED because they are executed whitin a transactional context.

7.9 Conclusion
Enterprise JavaBeans simplifies the developpers tasks with component transactionality as we saw in this chapter. Although, the Enterprise JavaBeans Specifications are lacking definition details and are not explaining the nature of the technology for important things such as: thread pooling concurrency control resource management. These details are left to the different EJB Server vendors. This can result into proprietary EJB solutions, meaning less portable. These technological issues should be addressed in the Enterprise JavaBeans specifications if we want to keep one of their goal: platform independence and portability.

Transactions

233

234

Developing Enterprise JavaBeans with VisualAge for Java

8 Security
The Internet has exposed distributed applications to possible malicious users. This has necessitated security management in these applications to ward off threats by hackers and virus attacks. The security feature of the Java language and the Virtual Machine (VM) along with the EJB specification address many of the security concerns. Enough literature is already available about the security features of the Java language and the VM. This chapter will delve only in the security features specific to EJB.

8.1 EJB Security


The EJBs themselves provide no security. Security for EJBs is derived from your system and is usually found withing your Web Server. Application Server provides security through servlets and their relationship to the Web Server. Enterprise JavaBeans require security features necessary to develop distributed transaction based applications. These are:
u Identifing and authenticating the caller u Managing access to resource based on security policies u Providing on-the-wire security

Copyright IBM Corp. 1999

235

8.2 Identifying and Authenticating the Caller

Figure 131. Access Control

Deploying an application on the Internet provides it access to audiences who could misuse it. It is necessary, therefore, for these applications to identify a priveleged user and to grant access only on a successful authentication.

8.3 Application Server Security


Protecting resources by access control lists
Users
A user is an identity that can be authenticated by the Web server. A user can represent a person or a computer. You cab name users however you like. Some common schemes include:
u strings, such as kilroy u distinguished names, such as uid=kilroy u email addresses, such as kilroy@was.here.com

Groups
Groups are sets of users. Groups provide an efficient way to manage large numbers of users because an administrator can specify permissions for an entire group at one time.

236

Developing Enterprise JavaBeans with VisualAge for Java

Usually, group members have something in common. For example, a company might have one group for managers and another for non-managerial employees. It may be that non-managers are given access to view sales data files, and managers are allowed both to view and to edit the sales data files. A person can be defined as both an individual user and as a member of a group. For example, the person Amy might be represented both as individual user amy and as a member of the group managers. When an individual user also belongs to a group, the individual access permissions override any group access permissions.

Resources
Resources are the valuable items accessible by your Web server:
u HTML files and directories, such as http://www.anycompany.com (Web

pages)
u Other files and directories, such as ftp://www.anycompany.com u Web applications: Java servlets or CGI programs

and by the IBM WebSphere Application Server:


u Java servlets u Connections, sockets, files, and other resources that can be used by

servlets
u Custom

servlets that enable access to enterprise resources and applications (such as databases)
Note

In the current release of WebSphere Advanced Edition 2.0 you cannot specify an EJB as a resource. Each resource can be protected by establishing a single access control list (ACL) for that resource, in a single realm (discussed below). The ACL specifies which users or groups are allowed to access or modify the resource. For each resource to protect, youll specify:
u An access control list (ACL) - a list defining who can use the resource u A security realm - a logical security area the resource belongs to u An authentication scheme - a way to verify users who ask for the resource

Security

237

The relationship among these items will more become apparent later in this discussion.

Permissions
Permissions represent the privileges required for accessing resources. An administrator protects resources by establishing access control lists to grant permissions to users and groups. Application Server lets you set a variety of permissions. For example, there are permissions to send and receive files, delete files, read and write files, load servlets, link to libraries, open and listen on sockets, and more. For descriptions of the available permissions, view the field help for the Access Control Lists page, the Manager page for setting permissions. Individual user permissions take precedence over group permissions. For example, if the user amy has both read and write access to a file, but the group amy belongs to has only read access to the file, amy remains able to read and write to the file because the individual user permission overrides the more restrictive group permission. (Even if the group permission is less restrictive than the user permission, the user permission overrides the group permission). Permissions are related to specific resources. Suppose a user has permission to view FileA and has permission to modify FileB. The users permission to modify FileB does not allow the user to modify FileA. Each permission applies to a particular resource and is nontransferable.

Realms
A realm is a database of users, groups, and access control lists. A user must be defined in a realm in order to access any resources belonging to that realm. A user can belong to several realms, but a user ID cannot be duplicated within a realm. For example, the user amy can belong to the realms fileRealm and anyRealm. Each of those realms can contain only one user named amy. The user amy can be given different permissions for different resources in each realm. A person, such as Kilroy, might have different user IDs in each realm. For example, he might be kilroy in the fileRealm, but is kilroy2 in the anyRealm because there is already a person in anyRealm using the user ID kilroy. Realms the Application Server ships with IBM WebSphere Application Server ships with some pre-established realms:

238

Developing Enterprise JavaBeans with VisualAge for Java

u The defaultRealm defines how users may access resources defined

locally. You can establish access control lists (discussed shortly) to determine which users and groups have access to which resources.
u The UNIX or NT realm is named for your operating system and defines

how users with accounts on the system the server is running on may access Application Server resources. Users and groups defined in the underlying system are shared by the IBM WebSphere Application Server, and continue to exist for as long as they exist in the underlying system. The Application Server Manager interface lets you view this realm; to change it, you must use the facilities provided by your operating system.
u The servletMgrRealm defines how servlets may access resources

defined remotely, such as remotely loaded servlets. The servletACL is the only access control list in this realm. When a remotely loaded, digitally-signed servlet tries to access a protected resource, the digital certificate in the servlet is compared with digital certificates associated with users in the servletMgrRealm. The servletACL decides whether permission is granted or denied. For example, suppose the digital certificate of userX is packaged in the anyServlet..JAR file. If userX is added to the servletMgrRealm, any servlet containing the same digital certificate as that of userX (found in anyServlet..JAR) may execute and access resources granted to userX.
u Finally, the LDAPRealm will be displayed if you have enabled a

directory service on the Directory Management page of the Application Server Manager. Users and groups defined in the directory service are shared by Application Server, and continue to exist for as long as they exist in the directory service or until you disable directory management support. The Application Server Manager interface lets you view this realm; to change it, you must use the facilities the LDAP server provides.

Access control lists


The access control list (ACL) associated with a resource specifies which users or groups in a realm are permitted to access the resource. ACLs, realms, and resources have the following relationship:
u A realm can contain many ACLs. u An ACL can belong to only one realm. u A realm can contain many resources. u A resource can belong to only one realm. u A resource is associated with only one ACL.

Security

239

u An ACL can be associated with many resources.

In some cases, a service does not require its customers to be in an access control list. For example, many Web page (HTTP) services make their documents available to all users without requiring them to register in an access control list (ACL).

Choosing authentication schemes and protocols


This section discusses authentication protocols, namely HTTP and HTTPS. Next, this section discusses authentication schemes, namely basic, digest, custom, and certificate authentication. Finally, this section discusses strategies for combining schemes and protocols.

About authentication protocols


If you have used a Web browser, you are most likely familiar with the Hypertext Transfer Protocol (HTTP), which determines how Web servers and Web browsers or other Web clients communicate with one another. If you have ever entered "http://. . ." into a browser to indicate a URL or file on the Web, you have used HTTP. HTTPS is a combination of the HTTP and SSL protocols. SSL, or Secure Socket Layer, is a network security protocol that can be used to provide the necessary security between server and client. If using Certificate authentication, which you will learn about shortly, you must use HTTPS. Otherwise, you can choose to use HTTP or HTTPS to protect your authentication data, the data that flows between client and server to verify that the client is allowed to access the server resources:
u If you choose HTTP, authentication data receives no protection. u If you choose HTTPS, authentication data is encrypted per the SSL

protocol. HTTPS is preferable to HTTP, unless you are operating in an already secure environment (or lack security concerns) and seek to avoid the overhead related to using HTTPS.

About authentication schemes


This describes and helps you choose among authentication schemes IBM WebSphere Application Server supports:
u Basic u Digest u Custom

240

Developing Enterprise JavaBeans with VisualAge for Java

u Certificate

Certificate authentication requires HTTPS; the other schemes can use either HTTP or HTTPS. An authentication protocol defines how authentication information (such as a user ID and password) is exchanged. IBM WebSphere Application Server requires clients to authenticate themselves to the server when requesting protected resources. IBM WebSphere Application Server supports:
u Basic authentication

Uses HTTP or HTTPS to request a user name and password from the client. The information is sent to the server in plain text for verification. All browsers support basic authentication. Consider using it if a user id and password provide sufficient authentication.
u Digest authentication

Uses HTTP or HTTPS to request a user name and password from the client. The user name and an encrypted form of the password (using a digest) are sent to the server for verification. Not all browsers support digest authentication. (Currently, only the Sun HotJava browser supports it). If a browser does not support digest authentication, its user cannot access the resources protected with this protocol.
u Custom authentication

Uses HTTP or HTTPS to request client information using a customized HTML form. The information is sent in plain text to the server for verification by a CGI or servlet. Use custom authentication when you need user authentication other than an id and password. For example, you can request a social security number from the user for authentication. With this protocol, you establish HTML forms to ask the user for data. Authentication is performed by server-side code (CGIs and servlets), not by the IBM WebSphere Application Server runtime application. If you use custom authentication, use HTTPS to protect the data.
u Certificate authentication

Uses HTTPS to request a client certificate. The SSL client authentication option must be enabled. The information is sent to the server for verification.

Security

241

Authentication using digital certificates is highly secure, and certificate authentication is often transparent to the user. The system or site administrator manages the client certificates. Often the task is delegated to certificate authority server software, such as the IBM Vault Registry product.

Combining authentication schemes and protocols


This section helps you decide whether to use HTTP or HTTPS in combination with your chosen authentication protocol: Basic, Digest, Custom, or Certificate authentication. As previously stated, unless you are in an environment where security is not a concern, HTTPS is usually preferred. Possible scenarios:
u For basic security, use Basic, Digest, or Custom authentication over HTTP u For more security, use Basic, Digest, or Custom authentication over

HTTPS
u For maximum security, use Certificate authentication over HTTPS

242

Developing Enterprise JavaBeans with VisualAge for Java

Part 2

Home Banking application

Copyright IBM Corp. 1999

243

244

Developing Enterprise JavaBeans with VisualAge for Java

9 Developing the Bank application


So far, you have learned how to develop every type of Enterprise JavaBeans using VisualAge for Java. We still need to understand how the Enterprise JavaBeans technology can be applied to a realistic application. For that purpose, we have defined an application supplying basic services for a banking system. The application provides user services to customers of the home banking application through a Web browser and administration services for an internal bank application.

Copyright IBM Corp. 1999

245

Figure 132. System View of the Bank Application

As you can see in Figure 132, internet users get access to the bank application through an HTTP server using servlets and JSPs pages. Servlets and JSPs pages deal with a session bean UserSB which implements all use cases. In a real environment, each use case could be mapped on individual session bean. This would allow the deployer to distribute session beans on different machines and provide better scalability. For each use case, UserSB session bean retrieves and invokes business methods on entity beans. These same entity beans can also be accessed by the AdminSB session bean implementing the use cases for administration purpose. The AdminSB implements use cases to create, remove bank accounts, customers. This type of activity could also be done through the Internet using JSP pages but seems more suitable for a Java based application taking advantage of the higher bandwidth generally available on an intranet network.

246

Developing Enterprise JavaBeans with VisualAge for Java

The Bank application entity beans are implemented as Container-managed persistence enterprise beans and have their persistent state managed by the container using the ITSOBANK database. In the following chapters, we describe how we have implemented the bank application. We do not describe how to create the client applications in this book. If you want to learn more you can refer to SG24-5423 book which addresses this part of the application. It is based on the same home banking application. Now we can continue by looking to the home banking applications class diagram.

9.1 Class Diagram


The class diagram contains four main objects: Bank, BankAccount, Customer, and TransactionRecord (see Figure 133) A Bank has many BankAccounts which may be of three types: CheckingAccount, SavingsAccount and CorporateAccount. Each transaction executed on a BankAccount is recorded as a TransactionRecord. Each BankAccount has an owner: a Customer, which has his own authentication information. The CorporateAccount is used to refer to a corporations that the customer does business with. For example the gas company could represent a corporate account.

Developing the Bank application

247

Figure 133. Bank Application Class Diagram

These classes are connected in different ways. A customer has a 1 to many relationship with a BankAccount. A BankAccount can be derived in CorporateAccount, SavingAccount or CheckingAccount. By introducing in the application basic object oriented concepts like aggregation and inheritance we put ourselves face to face with some of the

248

Developing Enterprise JavaBeans with VisualAge for Java

current Enterprise JavaBeans specification limitations. It does not yet addresses these problems and the tools do not yet provide help either. Because we believe that readers of this book will expect to find some guidance in solving these problems, we have investigated and propose a way to implement inheritance and aggregation. The solutions used in this book to solve these very difficult problems are described in the following chapters: Chapter 10, Relationships on page 251 and Chapter 11, Inheritance on page 265.

Developing the Bank application

249

250

Developing Enterprise JavaBeans with VisualAge for Java

10 Relationships
10.1 Problem description
As we have already mentionned, the Enterprise JavaBeans specification 1.0 does not define how associations must be supported. The current version 2.1 of VisualAge for Java does not support EJB associations either. To be able to build the one-to-many relationships in our banking application, we developed a relation package (itso.bank.ejb.relation) which wraps the association complexity.

10.2 Relation package (itso.bank.ejb.relation)


Overview
The itso.bank.ejb.relation package includes two classes (ManyLink and SingleLink) that support implementing persistent one-to-many associations between entity beans depending on storing and retrieving primary or foreign key values in a database. The one-to-many relationships are mapped to backward pointing foreign-key references.

Copyright IBM Corp. 1999

251

Class ManyLink implements the multi-value association end. Depending on the relation type parameter in the constructor, ManyLink supports an aggregation association (the parent controls the live cycles of its children) or a normal association. Class SingleLink is the single-valued inverse association end of the one-to-many relationship.

Responsibilities of the Link classes


u Maintaining the object-level referential-integrity

Mutators (set-methods) and collection add/remove methods automatically invoke the appropriate referential integrity maintenance behavior, such as updating the inverse association end. For aggregation associations the operations performed on the associations owner are cascaded to the member objects. For example, deletion of the associations owner object causes the member objects to be deleted: bank.remove() causes customer.remove(). Also when a member object is removed from the association the member is deleted: bank.removeCustomer(customer) causes customer.remove().
u Retrieving the member(s) at the other association end

Responsibilities of the bean developer


The user of the link classes is responsible for :
u defining the primary / foreign key in the entity bean u creating a customized finder method for the multi-valued association end u instantiating the link object in the entity bean u implementing the accessor methods in the entity bean by invoking the

appropriate methods of the link classes.


u maintaining the life cycle state of the link classes. The user has to set the

state of the link to "uninitialized" in the ejbLoad() method of the entity bean.
u invoking the appropriate link methods [ManyLink.removeAllMembers() /

SingleLink.setValue(null)] in the ejbRemove() method of the entity bean.


u defining the entity bean on both side of the association as REENTRANT

(Properties pane)

252

Developing Enterprise JavaBeans with VisualAge for Java

Design Considerations
In this section we describe the design considerations for the one-to-many relationship implementation (aggregation or normal association)
u Persistent association technique

There are different techniques to implement persistent association. Our implementation depends on storing and retrieving primary or foreign key values in the database.
u Usability

Our solution hides the association complexity in link classes. Entity beans delegate the relationship maintenance and members retrieval to the relation package. Two link objects are involved in each one-to-many relationship: at the multi-valued association end the entity bean owns a ManyLink object, the entity bean at the single-valued association end has a SingleLink object. A link object gets the association-relevant parameters from the entity at creation time (for example: relationship type [aggregation or normal association], role of the class, name of the primary / foreign key). To be able to retrieve and maintain the association members, the link objects use introspection (java. reflect package). The link objects invokes the appropriate EJB homes to retrieve the member(s). Example : The SingleLink object in a CustomerBean entity invokes bankHome.findByPrimaryKey(bankId) to get the bank reference of a customer. CustomerBean has a public instance variable which represents the bank foreign key in the customer object. SingleLink gets the foreign key value from its entity and passes the value in the findbyPrimaryKey call. The ManyLink object in a BankBean invokes customerHome.findByBankId(bankId) to retrieve the customers of a bank and gets the parameter value from its entity key object (BankKey). The SingleLink object updates the foreign key instance variable of its entity. Making the foreign key value persistent is the responsibility of the EJB container (CMP entity) or the bean (BMP entity). The relation package supports CMP and BMP entities.
u Database design

When persistent associations are based on database keys the associations

Relationships

253

are explicitly mapped to the primary-key/foreign-key relationships defined in the relational database. One-to-many relationships are mapped to backward pointing foreign-key reference (the child table refers to the parent table). Example: To map the one-to-many relationship between Bank and Customer the Customer table has a foreign key field (bankId) which points to the primary key field of the Bank table.
u Introspection

A link object gets the association-relevant parameters (for example : relationship type, role, name of primary / foreign key) at run time (constructor parameters). To be able to retrieve the members and maintain the associations, the link objects are working with introspection (package java. reflect).
u EJB server compatibility

We have tested the relation package with WebSphere 2.0 Advanced. We expect that our solution runs on other EJB servers supporting relational database persistence.

Using the Link classes


Prerequisite (package itso.bank.ejb.base)
Entity beans have to be extend from itso.bank.ejb.base.ITSOEntityBean, their remote interfaces from itso.bank.ejb.base.ITSOEntity. ITSOEntityBean maintains the entity context and the live cycle state of the bean (for example : creating, created, removing). The entity subclass has no context instance variable and forwards the context reference to the superclass in the setEntityContext method. The ejb callback methods (ejbCreate, ejbPostCreate, setEntityContext, ejbActivate, ejbLoad, ejbStore, ejbPassivate, ejbRemove, unsetEntityContext) call the appropriate method of the superclass (first statement in the method implementation)

Naming conventions
In this section we describe itso.bank.ejb.relation package. the naming conventions of the

254

Developing Enterprise JavaBeans with VisualAge for Java

Accessor methods
The user of the itso.bank.ejb.relation package has to define the accessor methods in the bean class and the Remote Interface. The naming rules for the multi-valued association end of a one-to-many relationship are :
u public void add<inverseRole>(EJBRemoteType) u public void remove<inverseRole>(EJBRemoteType) u public Enumeration get<inverseRole>s()

The <inverseRole> indicates the role played by the entity bean at the other end of the association. It is a parameter in the constructor of the ManyLink class and has to correspond to the Remote Interface name of the inverse entity bean. Each of the methods throws java.rmi.RemoteException. For the BankBean class we define the accessor methods :
u public void addCustomer(Customer) throws RemoteException u public void removeCustomer(Customer) throws RemoteException u public Enumeration getCustomers() throws RemoteException

The naming rules for the single-valued inverse association end are :
u public void set<inverseRole>(EJBRemoteType) Note : If the one-to-many association is an aggregation, no set method is needed. The parent reference has to be passed in the ejbcreate( ...) and ejbPostCreate( ... ) methods of the child entity bean. The association type is a parameter in the constructor of the ManyLink class owned by the entity bean at the other end of the association. u public void get<inverseRole>()

The <inverseRole> indicates the role played by the entity bean at the other end of the association. It is a parameter in the constructor of the SingleLink class and has to correspond to the Remote Interface name of the bean. Each methods throws java.rmi.RemoteException. The Bank - Customer relationship is an aggregation. For the CustomerBean class we define :
u public void getBank() throws RemoteException u public void ejbCreate(CustomerKey customerKey, Bank parent, ...)

throws RemoteException
u public void ejbPostCreate(CustomerKey customerKey, Bank parent, ...)

throws RemoteException

Relationships

255

Classes and Interfaces


The user of the itso.bank.ejb.relation package has to follow the standard naming rules for classes and Interfaces of the SmartGuide (Create EJB). For the bank EJB we define :
u BankBean class u BankKey class

The current implementation of the itso.bank.ejb.relation package supports bean key classes with one instance variable (no compound keys allowed). The instance variable has to be public.
u Bank interface u BankHome interface

For the customer EJB we define :


u CustomerBean class u CustomerKey class u Customer interface

Using the ManyLink class


In this section we describe how we use the ManyLink class in the link owner Bank entity bean to implement the multi-valued association end of the Bank - Customer association (one-to-many relationship).
u Defining the ManyLink class in the link owner entity bean : public class BankBean extends ITSOEntityBean implements javax.ejb.EntityBean { private ManyLink customerLink; } u Instantiating / accessing the ManyLink object

We lazy initialize the link object when it is used for the first time.
private ManyLink getCustomerLink() throws java.rmi.RemoteException { if (customerLink == null) customerLink = new ManyLink(this, "Customer", "itso.bank", "findByBankId", "primaryKey", ManyLink.AGGREGATION); return customerLink; } u Retrieving the customers public Enumeration getCustomers() throws RemoteException { return getCustomerLink().getMembers();

256

Developing Enterprise JavaBeans with VisualAge for Java

} u Adding a customer

The method is called from the SingleLink object owned by the entity of the other end of the association when a new customer is created.
public void addCustomer(Customer customer) throws java.rmi.RemoteException { getCustomerLink().addMember(customer); } u Removing a customer

The ManyLink object removes the relationship. Because we defined the association as an aggregation (constructor of ManyLink) the link object deletes the customer (child of the aggregate).
public void removeCustomer(Customer customer) throws java.rmi.RemoteException { getCustomerLink().removeMember(customer); } Note : customer.remove() gives the same result. u Maintaining the life cycle state of the the link object

The ejbLoad() method of the link owners entity bean sets the life cycle state of the link as uninitialized. The ManyLink object initializes its member collection during the next accessor call by invoking the home query method of the inverse association end bean (CustomerHome).The query members method name is a parameter of the ManyLink constructor.
public void ejbLoad () throws java.rmi.RemoteException { getCustomerLink().setUninitialized(); } u Removing the bank

Because we defined the association as an aggregation (constructor of ManyLink) the link object deletes all his children (customers) during the delete process of his owner entity bean.
public void ejbRemove() throws java.rmi.RemoteException { super.ejbRemove(); getCustomerLink().removeAllMembers(); }

Using the SingleLink class


In this section we describe how we use the SingleLink class in the link owner Customer entity bean to implement the single-valued inverse association end of the Bank - Customer association (one-to-many relationship).
u Defining the SingleLink class in the link owner entity bean :

Relationships

257

public class CustomerBean extends ITSOEntityBean implements javax.ejb.EntityBean { private SingleLink bankLink; public String primaryKey; public String bankForeignKey; } u Instantiating / accessing the SingleLink object

We lazy initialize the the link object when it is used for the first time.
private SingleLink getBankLink() throws java.rmi.RemoteException { if (bankLink == null) bankLink = new SingleLink(this, "Bank", "itso.bank", "bankForeignKey", "primaryKey"); return bankLink; } u Retrieving the bank public Bank getBank() throws RemoteException { return (Bank) getBankLink().getValue(); } u Setting the bank

public void ejbCreate(CustomerKey customerKey, Bank bank, ... ) throws RemoteException {


super.ejbCreate(); //superclass maintains the entity live cycle state primaryKey = customerKey.primaryKey; getBankLink().setValue(bank); } public void ejbPostCreate(CustomerKey customerKey, Bank bank, ...) throws RemoteException { super.ejbPostCreate(); //superclass maintains the entity live cycle state getBankLink().setValue(bank); }

A customer is a part of a bank (Bank - Customer is an aggregation association). In CustomerBean.ejbCreate(...) and CustomerBean.ejbPostCreate(...) we pass the reference to the aggregate of the part (Bank). CustomerBean has no setBank(Bank) method (a customer can not change the aggregate). SingleLink.setValue(EJBObject) called from ejbCreate(..) sets the foreign key instance variable in link owners entity to the primary key of link owners aggregate. Column BANKID in table CUSTOMER is a non nullable field. Not setting the foreign key in ejbCreate(..) results in an SQL error. We pass the foreign key field name and the primary key field name of the aggregate bean key in the constructor of SingleLink.

258

Developing Enterprise JavaBeans with VisualAge for Java

SingleLink.setValue(EJBObject) called from ejbPostCreate(..) sets the value of the association end and updates the inverse association end by calling the appropriate add member method of the owner aggregate and passing the link owners reference (its EJBObject reference). The ejbObject reference is accessible in the postCreate(..) method of the link owners entity.
u Maintaining the life cycle state of the the link object

The ejbLoad() method of the link owners entity sets the life cycle state of the link as uninitialized. The SingleLink object initializes its member value during the next accessor call by invoking the home of the inverse association end :
bankHome.findByPrimaryKey (primaryKeyOfBank) public void ejbLoad () throws java.rmi.RemoteException { super.ejbLoad(); getBankLink().setUninitialized(); } u Removing the customer public void ejbRemove() throws java.rmi.RemoteException { super.ejbRemove(); //superclass maintains the entity live cycle state bank.setValue(null); }

SingleLink.setValue(EJBObject) called from CustomerBean.ejbRemove(..) sets the value of the association end to null and updates the inverse association end by calling the appropriate remove member method of the owner aggregate. Note : bank.removeCustomer(customer) gives the same result.

Description of the Link classes


To make the implementation of the link classes the most generic possible we intensively work with the package java.reflect. Class ManyLink and SingleLink create objects, constructors, methods and fields dynamically during runtime depending on the parameters passed to the ManyLink and SingleLink constructors.

Class ManyLink
Constructor
ManyLink(ITSOEntityBean linkOwner,

Relationships

259

String inverseRole, String packageNameInverseAssociationEnd, String queryMembersMethodName, String primaryKeyFieldNameOfLinkOwnerBeanKey, int relationType) throws RemoteException

The constructor has six parameters : 1. reference to the owner of the link (entity bean) 2. inverse role (role of the entity bean at the other end of the association). The name of the role has to correspond to the Remote Interface of the inverse entity bean. 3. package name of the inverse association end (ManyLink expects the bean key class of the link owner entity in the same package as the link owner). 4. name of the members querying method of the inverse home class. Extensions to the home provide the services for finding the members of a many-link. 5. name of the primary key field in the key class of the link owner entity. The primary key field has to be public. The ManyLink object gets the field from the key class and passes the value as foreign key in the members querying method (see previous parameter). 6. relation type : Aggregation [ManyLink.AGGREGATION] controls the life cycle of the member objects or normal association [ManyLink.NORMAL_ASSOCIATION].

public Enumeration getMembers()


u If the member vector is not initialized yet: refreshes the vector by

invoking the query members method of the inverse home (home of the entity at the other end of the association) and passes the primary key of the link owners entity as a parameter. The name of the query members method and the name of the primary key field of the link owners bean key are parameters of the ManyLink constructor.
u converts the member vector to EJBObjectEnumeration and returns to

enumeration.

public void addMember(ITSOEntity entityToAdd)


u refreshes the member vector if the vector is not initialized yet (see

getMembers() method).
u if the member vector does not contain the member reference : adds the

reference to the vector.

260

Developing Enterprise JavaBeans with VisualAge for Java

u if the relation is a normal association (not an aggregation) : updates the

singled-value reference at the other end of the association by invoking the appropriate set method of the inverse bean and passing the EJBObject reference of the link owners entity as a parameter.
u if the relation is an aggregation : the parent reference is passed to the

child entity in the ejbCreate(...) and ejbPostCreate(...) method of the child. Both methods pass the parent reference to the SingleLink object by invoking singleLink.setValue(EJBObject parentReference). SingleLink invokes the appropriate add method of the inverse multi-valued side of the association.

public void removeMember(ITSOEntity entityToRemove)


u refreshes the member vector if the vector is not initialized yet (see

getMembers() method).
u if the member vector does contain the member reference : remove the

reference in the vector.


u if the relation is a normal association (not an aggregation): udpates the

singled-value reference at the other end of the association by invoking the appropriate set method of the inverse bean and passing a null value.
u if the relation is an aggregation : deletes the child by invoking the childs

remove() method.

public void removeAllMembers()


u refreshes the member vector if the vector is not initialized yet (see

getMembers() method).
u invokes removeMember(entityToRemove) for each member.

Class SingleLink
Constructor
SingleLink(ITSOEntityBean linkOwner, String inverseRole, String packageNameInverseAssociationEnd, String foreignKeyFieldName, String primaryKeyFieldNameOfInverseBeanKey) throws RemoteException

The constructor has six parameters : 1. reference to the owner of the link (entity bean) 2. inverse role (role of the entity bean at the other end of the association). The name of the role has to correspond to the Remote Interface of the inverse entity bean

Relationships

261

3. package name of the inverse association end 4. name of the foreign key field in the link owner entity. 5. name of the primary key field in the key class of the inverse association name of the role (Customer)

public ITSOEntity getValue()


u initializes the object reference to the singled-value association end (if not

initialized yet). The next paragraphs describe the initialization process :


u gets the foreign key value from the link owners entity bean. The name of

the (public) foreign key field is a parameter in the SingleLink constructor.


u creates the inverse bean key object by invoking the constructor of the

inverse bean key class (parameter : foreign key).


u invokes findByPrimaryKey method of the inverse beans home class

(parameter : inverse bean key object).


u initializes the object reference (singled-value association end) with the

result of the findByPrimaryKey method.

public void setValue(ITSOEntity newRelation)


u initializes the object reference to the singled-value association end (if not

initialized yet) (see getValue() method).


u determines the type of relationship update (new, delete, update) u new relationship (current relation : null / new relation : not null) :

If the link owners entity bean is in the pre-creating state [calling method : ejbCreate(...)] : sets the foreign key instance variable of link owners entity bean to the primary key value of newRelation (parameter in the setValue() method).
Note : not setting a non nullable foreign key for CMP entities during ejbCreate(...) results in an SQL error when the container tries to insert the row after ejbCreate(...) has ended. Updating the object references on both end of the association during ejbCreate(...) is not possible because the link owners entity has no identity yet.

If the link owners entity bean is not in the pre-creating state [calling method : ejbPostCreate(...) or wrapper method set<inverseRole>(EJBRemoteType)] : sets the foreign key instance variable of the link owners entity (see above), sets the value of the association end to newRelation and updates the inverse association end by calling the appropriate add member method and passing the link owners EJBObject interface (also referred as the remote interface).

262

Developing Enterprise JavaBeans with VisualAge for Java

Note : <inverseRole> is a parameter in the constructor of SingleLink class. u delete relationship (current relation : not null / new relation : null) : sets the foreign key instance variable of the link owners entity and the value of the association end to null and updates the inverse association end by calling the appropriate remove member method and passing the link owners EJBObject interface (also referred as the remote interface). u update relationship (current relation : not null / new relation : not null) :

delete old relationship, then create new association.

Limitations
The itso.bank.ejb.relation package has the following limitations :
u The SingleLink class implements the single-valued end of a one-to-many

association (the entity bean at the other end of the association has to own a ManyLink object). One-to-one association in both directions are not supported..
u No compound keys allowed. Bean key classes have one (public) instance

variable.

Relationships

263

264

Developing Enterprise JavaBeans with VisualAge for Java

11 Inheritance
In this chapter we describe how Entity EJBs can be used to display polymorphism.

11.1 Inheritance
The main motive for implementing inheritance is to support polymorphism and to provide reuse of the objects. Polymorphism in the Object-Oriented sense means using a superclass variable to represent a subclass object. For example, a bank could have different types of accounts like Savings, Checkings and Corporate. Polymorphism implies using an object (a BankAccount) to represent any type of account. The 1.0 version of the EJB specification does not provide inheritance support between EJBs. In this chapter we describe the programming model to support inheritance and a sample implementation using this model.

Copyright IBM Corp. 1999

265

11.2 Requirements for the Inheritance


Inheritance implementation for Entity beans implies providing the following functionalities:
u Specifying an is-a relationship among Entity beans, like, a Saving

Account is a Bank Account


u Making the findByPrimaryKey method in the Home Interface return the

target class along with its subclasses, that is, a search for all the BankAccounts returns even the Saving Accounts, Checking Accounts and Corporate Accounts.
u Making relationship finders return heterogenous results, containing

instances of the related class and its subclasses

11.3 Programming Model


Inheritance affects the different components of an EJB: the home interface, the EJB remote interface, the EJB implementation and the primary key class. Since Entity beans can not directly inherit the properties and behavior of another Entity bean, we describe a logical inheritance as follows: We identify an entity EJB that will serve as the parent EJB of a set of child EJBs. This bean is referred to as the Parent bean and is described by the following:
u Remote interface, Parent u Home interface, ParentHome u Bean implementation class, ParentBean u Primary key class, ParentKey

A subclass of Parent bean called Child bean would have the following characteristics:
u Remote interface, Child u Home interface, ChildHome u Bean implementation class ChildBean u Primary key class, ParentKey

266

Developing Enterprise JavaBeans with VisualAge for Java

Remote Interface
The remote interface of the child EJB, Child, must extend the remote interface of the parent EJB, Parent. This ensures that an instance of the child EJB may be used where an instance of the parent EJB is expected, one of the important benefits of inheritance.

EJB Homes
The home of the Child bean, ChildHome, must not extend the Parent home, ParentHome. However, it is important to define the relationship between methods on the ParentHome and ChildHome interfaces. A create method on ParentHome can only create a Parent bean instance, and a create method on ChildHome creates both a Child bean and a Parent bean instance. A remove method on ParentHome can remove Parent bean instances only. A remove method on ChildHome removes both the Child and Parent bean instances. A custom finder method on ParentHome returns an Enumeration that may contain Parent bean instances. The determination of the actual contents of the Enumeration is described as an example in Accessing the BankAccount Hierarchy on page 275. For bean implementations that are the root of an inheritance hierarchy, we define a discriminator field which determines that actual type of the instance. A getter method must also be defined for the discriminator and this method should be promoted to the remote interface. For a bean that inherits from a parent class, the child beans implementation class must extend from a Proxy class. The Proxy superclass contains all the methods defined in the remote interface of the parent bean. An invocation on any of these methods is redirected to an instance of the parent bean. A client must not work directly with an instance of the Parent bean but only with the Child beans. The discriminator field is useful in identifying the specific child bean to which the instance belongs to. The client then looks up the corresponding child home for obtaining the true instance.

Primary Key Class


All entity beans in an inheritance must use the same Java key class for their primary keys.

Inheritance

267

11.4 Mapping Schemes for Relational Databases


Inheritance support implies support for multiple patterns for mapping a hierachy of types to one or more database tables.
u "Single-table" mapping: All the types in the hierarchy map to the same

table, a discriminator column identifies the type of object to be instantiated from a row, tables are not fully-normalized, but the whole hierarchy can be accessed easily.

Figure 134. Single-table mapping u "Root/leaf" mapping: The root of the hierarchy specifies the root table

which also provides a discriminator column. Each subtype specifies the leaf table which must be joined to gather the subclass-specific columns. Tables are fully-normalized, but multiple joins can be required to read a single instance, and joins and unions are required to read a hierarchy.

268

Developing Enterprise JavaBeans with VisualAge for Java

Figure 135. Root/leaf mapping u "Distinct-table" mapping: Each class in the hierarchy maps to a separate

table, which contains the complete row for that type. Tables are likely not normalized, access to a single type requires no joins, but access to a hierarchy always requires unions. Since the tables do not have to be related, key consistency problems between the tables can make this pattern very difficult to automate.

Figure 136. Distinct-table mapping

Note: Our programming model supports only the root/leaf mapping.

Inheritance

269

11.5 Developing the BankAccount Hierarchy

Figure 137. BankAccount Inheritance Hierarchy

The Above class diagram has a superclass BankAccount and its subclassesCorporateAccount, SavingsAccount and CheckingAccount. We now develop the EJBs to match this hierarchy.

Developing the Remote Interfaces


The remote interfaces of the Entity beans contain the methods of the respective classes in the hierarchy. The remote interfaces of the CorporateAccount, SavingsAccount and CheckingAccount beans extend from the BankAccount remote interface.

270

Developing Enterprise JavaBeans with VisualAge for Java

Note

VisualAge for Java does not generate the deployment classes properly for remote interfaces which extend from other interfaces. The tool does not identify any of the methods defined in the super class. You need to manually copy all the methods from the superclass (interface) to the remote interface even though there is an inheritance to enable the tool to generate the classes without any errors.

The BankAccount Superclass


You can develop the BankAccountBean just like any other entity bean. Create a CMP Entity bean (BankAccount) having key class BankAccountKey, remote interface BankAccount and home interface BankAccountHome. Implement the business methods, defined in the class diagram, and add them to the beans Remote interface. We have implicitly described a discriminator field, accountType, in the superclass. This field will be used to extract the actual instance of the subclass. Based on the value of this field the appropriate Homes of the child beans are looked up and the instance of the subclass obtained.

Developing Subclass EJBs


We implement inheritance by delegation, that is, the sub-class has a reference to a super-class object rather than inheritance of its visible methods and fields. In the Bank Application, it means the sub-classes, like SavingsAccountBean, define wrapper methods for the super classes methods and within these wrappers delegate responsibility to the actual BankAccount object. In order to obtain a degree of code reuse, which is one of the design goals of inheritance, we define an abstract class BankAccountProxy, which has the wrappers and does the necessary delegation. All the subclassesSavingsAccountBean, CheckingAccountBean and CorporateAccountBean extend from this class. The Subclasses should use the same Key class as the one used by the super class, namely, BankAccountKey. This is done in order to be able to identify both the superclass and the subclass with the same key.

Inheritance

271

Figure 138. Simulating Inheritance by delegation

An obvious question would be as to why SavingsAccountBean has not been directly extended from the BankAccountBean. The problem with the direct inheritance approach is that the super class bean, BankAccountBean, is not registered with the Home, BankAccountHome. Entity beans not registered with their respective homes (via create or find methods) operate just like any other Java object inaccessible to container callbacks and hence can not avail the transaction, persistence and security features.

Proxy Superclass
The BankAccountProxy class contains the methods that wrap the remote methods of the BankAccount bean. It also contains a method getProxy() that returns the actual BankAccount object. All the remote method calls are routed to this object. The BankAccount object is obtained after a lazy initialization. In the initialization, the Home interface, BankAccountHome, is looked up using the findByPrimaryKey method passing the same key as that of the subclass.
if (proxy == null) { proxy = getBankAccountHome().findByPrimaryKey( getKey() ); }

The getKey() method is an abstract method whose implementation is provided in the subclass, where the primary key of the instance is returned as follows:
if (entityContext != null) return (BankAccountBean) entityContext.getPrimaryKey();

272

Developing Enterprise JavaBeans with VisualAge for Java

We also define a protected method createBankAccount which is invoked within the ejbCreate method of the subclass in order to create an instance of the superclass bean. In the createBankAccount method, the create(...) method is invoked on the BankAccountHome passing the necessary parameters.
protected void createBankAccount(BankAccountKey key, ...) { proxy = getBankAccountHome().create(key, ...); }

The state of the actual BankAccount object that the BankAccountProxy is using must be synchronized with the current state of the subclass entity bean, like the SavingsAccount bean. This can be done by initializing/uninitializing the proxy object in the container callback methods invoked on the subclass entity bean during different stages of its lifecycle:
u ejbPassivate

The container invokes this method when it decides to send the entity to the pooled state. After the completion of this method, the proxy object no longer corresponds to the state of the subclass. We uninitialize the proxy object in this method, by setting it to null.
u ejbActivate

The container invokes this method when it sends the entity to the ready state. At this point the proxy object is out of synch with subclasses state. Its state will not be determined till the next ejbLoad and hence left uninitialized.
u ejbRemove

When the subclass is being removed, even the superclass needs to be removed. In this method we remove the proxy object by a getProxy().remove() operation.
u When any of the remote methods of the superclass remote methods are

invoked the actual proxy object needs to be located in order to invoke the remote methods on it. This is done by a lazy initialization described earlier in this section.
u When a new instance of the subclass is created a new instance of the

superclass entity bean must be created and the proxy objects value set to the created instance. We defer the loading of the super class until any of its remote methods are invoked. This way there is not unnecessary Home interface lookup which is an expensive operation.

Inheritance

273

Defining the Inheritance Mapping Scheme


In our implementation we work with the root/leaf inheritance map to represent the tables in the database. In this mapping scheme there is a 1-to-1 correspondence between the tables and the classes. The root table contains the columns matching the fields of the super class and the leaf tables contain the columns matching the fields of the specific subclasses and a foreign key matching the primary key of the root table.

BankAccount accountId bankId custId accType balance

BankAccount Table

SavingsAccount Table SavingsAccount minAmount

Figure 139. Mapping the BankAccount Hierarchy to the Database

The figure above shows how the SavingsAccount and the BankAccount beans can be mapped using the root/leaf mechanism:
u All the fields of the superclass, BankAccount, are mapped to the

BankAccount table as distinct columns with ACCID (accountId) being the primary key for the table
u The fields of the SavingsAccount class are mapped similarly to the

SavingsAccount table with an additional field ACCID being the primary key
u ACCID in the BankAccount table acts as the foreign key in the

SavingsAccount table.

274

Developing Enterprise JavaBeans with VisualAge for Java

We prefer this approach over the single table and distinct table mapping for the following reasons:
u Classes can be added to the hierarchy without altering any of the existing

tables. This is not true for single table mapping where the fields of the new class in the hierarchy must be mapped to new columns in the single table.
u The resulting tables are compacter than in the distinct table mapping. In

the distinct table mapping all the columns of the parents table are duplicated in the tables of the subclasses.
u In the single table mapping, when different subclass beans share the

same key class, it is possible for the findByPrimaryKey method to return an instance which does not correspond to the specified bean. For example, the findByPrimaryKey method invoked on the SavingsAccountHome passing a BankAccountKey may return a CheckingAccount. The restriction on the type of inheritance mapping may hamper development of EJBs from existing tables. You also can not define any foreign key constraints (DELETE, RESTRICT) on the subclasses table using the primary key of the superclasses table.

11.6 Accessing the BankAccount Hierarchy


We now describe how different instances in the BankAccount hierarchy can be accessed by a client. According to our programming model, every Entity bean has an associated Home interface. Thus we have a SavingsAccountHome for the SavingsAccount bean, a BankAccountHome for the BankAccount bean and likewise. Implementing inheritance by delegation results in the creation of two instances the child bean and the parent bean when a create method is invoked on the child beans home interface. When a find<METHOD> is invoked on the parent beans home, only the parent beans instances are returned and not of its subclasses. The instances returned do not represent the true identity of the created entity bean but only the portion corresponding to the parent bean. We describe a mechanism to extract the original instances, which represent the instances of the child beans. 1. A client invokes a find<METHOD> on the Parent beans Home, BankAccountHome

Inheritance

275

2. The find<METHOD> returns an instance or an enumeration of instances of the Parent bean 3. The client obtains the discriminator field of an instance by invoking the getter method for the discriminator field. The value of this field is one of SAVINGS, PAYEE or CHECKING 4. The client determines the child beans home to be looked up based on the value of the discriminator SavingsAccountHome for SAVINGS, CorporateAccountHome for PAYEE and CheckingAccountHome for CHECKING 5. The client invokes the findByPrimaryKey method on the child beans home passing the primary key of the parent beans instance 6. The result of the above find method is the actual instance which should be used by the client When a client attempts to invoke methods belonging to the subclass, the object needs to be narrowed using the necessary CORBA helper class in the following way:
public void main(String[] args) { /** * Find a specific BankAccount using the Key * If its a SavingsAccount determine the Minimum amount * We could have used the specific home - SavingsAccountHome but this step * is necessary when you are using * the parents Home to lookup a child bean */ BankAccountHome bankAcHome = .... BankAccount ba = bankAcHome.findByPrimaryKey(...); if (ba.getAccountType().equals("Saving") ) { SavingsAccount sa = SavingsAccountHelper.narrow(ba); /* * we cannot directly do * SavingsAccount sa = bankAcHome.findByPrimaryKey(".."); * and we also cannot type cast it directly like sa = (SavingsAccount) ba; */ sa.getMinimumAmount(); // get the minimum amount } }

The TypeConverter Class


We define a TypeConverter Class which performs the task of obtaining the actual instance from the parent beans instance.

276

Developing Enterprise JavaBeans with VisualAge for Java

It contains two methods to convert the instance of the parent bean to an instance of the child bean typeCast(BankAccount) and typeCastEnumeration(Enumeration). The typeCast method implements the steps described earlier to return the actual instance from an instance of the parent bean.
public static BankAccount typeCast(BankAccount parent) throws RemoteException{ String discriminator = parent.getAccountType(); if ("SAVINGS".equals(discriminator)) return getSavingsHome().findByPrimaryKey( parent.getPrimaryKey()); if ("PAYEE".equals(discriminator)) return getCorporateHome().findByPrimaryKey(parent.getPrimaryKey()); if ("CHECKING".equals(discriminator)) return getCheckingHome().findByPrimaryKey(parent.getPrimaryKey()); throw new RemoteException("Could not locate actual instance"); }

The typeCastEnumeration method returns an Enumeration of the actual instances from an Enumeration of the instances of the parent bean.
public static Enumeration typeCastEnumeration(Enumeration enum) throws RemoteException{ Vector actual = new Vector(); while (enum.hasMoreElements()) { actual.addElement( typeCast((BankAccount) enum.nextElement()); } return actual.elements(); }

The get<ChildBean>Home returns the home of the child beans.

11.7 Relationships and Inheritance


The Relationship classes, SingleLink and ManyLink, described in Chapter 10, Relationships on page 251 have to be enhanced when the inverse role is an Entity bean at the root of an inheritance hierarchy. Such a relationship is required when the parent entity bean is expected to display polymorphic behavior. In our examples, we use the BankAccount hierarchy with the BankAccount at the root as the inverse role of the relationships. Similiar changes have to be made in regard to naming when using any other inheritance hierarchies.

Inheritance

277

SingleLink
In a Bank, a TransactionRecord is created by a particular BankAccount which could be a SavingsAccount, CorporateAccount or a CheckingAccount. We extend the SingleLink class to represent an association between the TransactionRecord and the BankAccount. The TransactionRecord uses the link class, BankAcountSingleLink, to set and obtain the value of the BankAccount reference. The BankAccountSingleLink extends the SingleLink class. Please refer to Class SingleLink on page 261 for more information about the SingleLink class. The usage of this class remains the same except as indicated below:

Constructor
The Constructor takes only the linkOwner and foreignKeyFieldName parameters. The inverseRole, packageNameInverseAssociationEnd and primaryKeyFieldNameOfInverseBeanKey are already known and their values are BankAccount, itso.bank.ejb and accountId respectively. The super classes constructor is invoked with these parameters in the body.

public BankAccount getBankAccount()


Within this method the actual instance of the BankAccount is determined using the TypeConverter class and returned. This method should be used in the link owners ejbCreate and ejbPostCreate methods to set the inverse role in the relationship.

ManyLink
In a similiar Bank scenario, a Customer has an aggregation of BankAccounts. A BankAccount in the aggregation could be a SavingsAccount, CheckingAccount or CorporateAccount. We extend the ManyLink class to represent the relationship between the Customer and the BankAccount(the root of the hierarchy). The Customer uses this link class, BankAccountManyLink, to add, remove and retrieve the BankAccounts. The BankAccountManyLink extends the ManyLink class. Please refer to Class ManyLink on page 259 for more information about the ManyLink Class. The usage of this class remains the same except as indicated below:

Constructor
The Constructor takes only the linkOwner, queryMembersMethodName, primaryKeyFieldNameOfLinkOwnerBankKey and relationType

278

Developing Enterprise JavaBeans with VisualAge for Java

parameters. The inverseRole and packageNameInverseAssociationEnd are already known and their values are BankAccount and itso.bank.ejb respectively. The super classes constructor is invoked with these parameters in the body.

public Enumeration getBankAccounts()


Within this method a vector of the BankAccounts is constructed from the super.getMembers() method. Every member of the vector is set to the actual instance using the TypeConverter class and the elements of this vector returned as an Enumeration. This method should be used in the link owners getter method to return the members of the aggregation.

public void addBankAccount(BankAccount acc)


This method invokes the super.addMember( ) passing the BankAccount as the entityToAdd. The advantage of using a method with this signature is the compile-time checking of the BankAccount class. This method should be used by the link owner to add a BankAccount to the aggregation.

public void removeBankAccount(BankAccount acc)


Within this method, the original instance of the BankAccount is obtained using the TypeConverter class and passed as the entityToRemove to super.removeMember(). This method should be used by the link owner to remove a BankAccount from the aggregation.

public void removeAllMembers()


Within this overridden method, the getBankAccounts() method is invoked and the returned Enumeration is traversed passing every member as an entity to remove to the super.removeMember(). This method should be used in the ejbRemove method of the link owner.

11.8 The Future of EJB Inheritance


As you might have noticed, implementing inheritance is not an easy task with Entity beans. There are plans afoot to support EJB inheritance in future releases of the EJB specification and VisualAge for Java/Websphere. Till then this approach serves as a generic approach towards supporting EJB inheritance without using any vendor-specific add ons.

Inheritance

279

280

Developing Enterprise JavaBeans with VisualAge for Java

12 Bank Implementation Entity Beans


In this chapter, we describe how to create the entity beans:
u Bank u Customer u BankAccount u SavingAccount u CheckingAccount u CorporateAccount u TransactionRecord

Copyright IBM Corp. 1999

281

12.1 Developing the BankAccount Hierarchy


In the bank application, we support inheritance between the super class BankAccount and CheckingAccount, SavingsAccount, CorporateAccount subclasses.

Developing the BankAccount Bean


The BankAccount bean has been described in The BankAccount Superclass on page 271. We now describe how the bean should be developed in order to support relationships. Create a new BankAccount bean in the ITSOBank group specifying the following information:
u Bean name: BankAccount u Bean type: Entity bean with container-managed fields (CMP) u Project: ITSOBank u Package: itso.bank.ejb u Class: BankAccountBean u Superclass: itso.bank.ejb.base.ITSOEntity u EJB Home Interface: BankAccountHome u EJB Remote Interface: BankAccount u EJB Key Class or Field: BankAccountKey

Add the CMP Fields


Add accountId(java.lang.String), accountType(java.lang.String), balance(java.math.BigDecimal), bankFK(java.lang.String) and customerFK(java.lang.String) as CMP fields to the BankAccountBean. Set accountId as the Key field. Provide getter methods for the accountId, accountType and balance fields and promote these methods to the Remote interface.

Modify the Generated Methods


We modify the ejbCreate and ejbPostCreate methods to have a formal parameter list BankAccountKey key, Customer cust, Bank bank, String accountType. The parameters represent the non-nullable fields defined in the database.

282

Developing Enterprise JavaBeans with VisualAge for Java

Add the Remote Methods


As per the class diagram (see Figure 133 on page 248), add the significant methods to the bean and promote them to the remote interface.

Specify the Relationships


According to the class Diagram, BankAccount has an association with a Bank and Customer object and an aggregation of TransactionRecord objects. To provide such a relationship in the EJB scenario we use the SingleLink and ManyLink classes described in Chapter 10, Relationships on page 251 as follows:
private transient itso.bank.ejb.relation.SingleLink bankLink = null; private transient itso.bank.ejb.relation.SingleLink customerLink = null; private transient itso.bank.ejb.relation.ManyLink transactionRecordLink = null;

The Links are initialized within private getter methods


bankLink = new SingleLink(this, "Bank", "itso.bank.ejb", "bankFK", "primaryKey"; customerLink = new SingleLink(this, "Customer", "itso.bank.ejb", "custFK", "primaryKey"; transactionRecordLink = new ManyLink(this, "TransactionRecord", "itso.bank.ejb", "findByAccountId", "accountId", ManyLink.AGGREGATION);

Add the necessary add, remove and accessor methods to support the different relationships. Make the necessary changes within the ejbCreate, ejbPostCreate, ejbActivate, ejbPassivate, setEntityContext and unsetEntityContext methods as described in Responsibilities of the bean developer on page 252.

Developing the Children EJBs


The Development of the children EJBs in the BankAccount hierarchy is described in detail in Developing Subclass EJBs on page 271.

12.2 Developing the Bank Entity Bean


Create a new Bank bean in the ITSOBank group specifying the following information:
u Bean name: Bank u Bean type: Entity bean with container-managed fields (CMP)

Bank Implementation Entity Beans

283

u Project: ITSOBank u Package: itso.bank.ejb u Class: BankBean u Superclass: itso.bank.ejb.base.ITSOEntityBean u EJB Home Interface: BankHome u EJB Remote Interface: Bank u EJB Key Class or Field: BankKey u import statements:

itso.bank.ejb.base.* itso.bank.ejb.relation.* itso.bank.ejb.inheritance.relation.*

Add Fields
CMP
For directions on how to add CMP fields see , Adding fields to the Bean on page 122.

Table 9. Create Field bankName


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed bankName String public none checked

public public yes

284

Developing Enterprise JavaBeans with VisualAge for Java

Transient
Table 10. Create Field customerLink
Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed customerLink itso.bank.ejb.relation.ManyLink private transient checked

private (none) no

Table 11. Create Field accountLink


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed accountLink itso.bank.ejb.inheritance.relation.BankAccountManyLink private transient checked

private (none) no

Bank Implementation Entity Beans

285

Add new methods


For directions on how to add a method to an EJB see , Adding methods to EJBs on page 41.
u addBankAccount public void addBankAccount(BankAccount account) throws java.rmi.RemoteException { traceMethod("start Bank.addBankAccount(BankAccount account)"); try { getBankAccountLink().addBankAccount(account); traceMethod("end Bank.addBankAccount(BankAccount account)"); } catch(Exception e) { throw wrapperNonRemoteException("BankBean.addBankAccount(BankAccount)", e); } } u addCustomer public void addCustomer(Customer customer) throws java.rmi.RemoteException { traceMethod("start Bank.addCustomer(Customer customer)"); try { getCustomerLink().addMember(customer); traceMethod("end Bank.addCustomer(Customer customer)"); } catch(Exception e) { throw wrapperNonRemoteException("BankBean.addCustomer(Customer)", e); } } u getBankAccounts public Enumeration getBankAccounts() throws RemoteException { traceMethod("getBankAccounts()"); return getBankAccountLink().getBankAccounts(); } u getBankId public String getBankId() throws RemoteException { traceMethod("getBankId()"); return primaryKey; } u getCustomers public Enumeration getCustomers() throws RemoteException { traceMethod("getCustomers()"); return getCustomerLink().getMembers(); }

286

Developing Enterprise JavaBeans with VisualAge for Java

u removeBankAccount public void removeBankAccount(BankAccount account) throws java.rmi.RemoteException { traceMethod("start Bank.removeBankAccount(BankAccount account)"); try { getBankAccountLink().removeBankAccount(account); traceMethod("end Bank.removeBankAccount(BankAccount account)"); } catch(Exception e) { throw wrapperNonRemoteException("BankBean.removeBankAccount(BankAccount)", e); } } u removeCustomer public void removeCustomer(Customer customer) throws java.rmi.RemoteException { traceMethod("start Bank.deleteCustomer(Customer customer)"); try { getCustomerLink().removeMember(customer); traceMethod("end Bank.deleteCustomer(Customer customer)"); } catch(Exception e) { throw wrapperNonRemoteException("BankBean.deleteCustomer(Customer)", e); } } u traceMethod private void traceMethod(String methodNameAsString) { String bankKeyAsString = null; Object ejbObject = null; try { bankKeyAsString = ((BankKey) getPrimaryKey()).primaryKey; ejbObject = getEJBObject(); } catch(RemoteException e) { bankKeyAsString = "unknown"; } System.out.println(">> " + methodNameAsString + " [" + this + "] / Key " + bankKeyAsString +" [EJBObject: " + ejbObject + "]"); }

Modify the Generated Methods


u ejbActivate public void ejbActivate() throws java.rmi.RemoteException { super.ejbActivate(); traceMethod("ejbActivate()"); }

Bank Implementation Entity Beans

287

u ejbCreate public void ejbCreate(BankKey key, String name) throws RemoteException { // All CMP fields should be intialized here. super.ejbCreate(); primaryKey = key.primaryKey; bankName = name; traceMethod("ejbCreate(BankKey)"); } u ejbLoad public void ejbLoad () throws java.rmi.RemoteException { super.ejbLoad(); getCustomerLink().setUninitialized(); getBankAccountLink().setUninitialized(); traceMethod("ejbLoad()"); } u ejbPassivate public void ejbPassivate() throws java.rmi.RemoteException { super.ejbPassivate(); traceMethod("ejbPassivate()"); } u ejbPostCreate public void ejbPostCreate(BankKey key, String name) throws java.rmi.RemoteException { super.ejbPostCreate(); traceMethod("ejbPostCreate(BankKey)"); } u ejbRemove public void ejbRemove() throws java.rmi.RemoteException { super.ejbRemove(); traceMethod("ejbRemove()"); getCustomerLink().removeAllMembers(); getBankAccountLink().removeAllMembers(); } u ejbStore public void ejbStore () throws java.rmi.RemoteException { super.ejbStore(); traceMethod("ejbStore()"); } u getBankAccountLink

288

Developing Enterprise JavaBeans with VisualAge for Java

private BankAccountManyLink getBankAccountLink() throws java.rmi.RemoteException { if (accountLink == null) //accountLink = new ManyLink(this, "BankAccount", "itso.bank.ejb", "findByBankId", "primaryKey", ManyLink.AGGREGATION); accountLink = new BankAccountManyLink(this, "findByBankId", "primaryKey", ManyLink.AGGREGATION); return accountLink; } u getCustomerLink private ManyLink getCustomerLink() throws java.rmi.RemoteException { if (customerLink == null) customerLink = new ManyLink(this, "Customer", "itso.bank.ejb", "findByBankId", "primaryKey", ManyLink.AGGREGATION); return customerLink; } u setEntityContext public void setEntityContext(EntityContext ctx) throws java.rmi.RemoteException { super.setEntityContext(ctx); } u unsetEntityContext public void unsetEntityContext() throws java.rmi.RemoteException { super.unsetEntityContext(); traceMethod("unsetEntityContext()"); }

Add Methods to the Remote Interface


Select the following methods and add them to the bean remote interface. For directions on how to add a method to the remote interface, see , Adding Methods to the Remote Interface on page 46.
u addBankAccount u addCustomer u getBankAccounts u getBankId u getBankName u getCustomers u removeBankAccount

Bank Implementation Entity Beans

289

u removeCustomer u setBankName

12.3 Developing the Customer Entity Bean


Create a new Customer bean in the ITSOBank group specifying the following information:
u Bean name: Customer u Bean type: Entity bean with container-managed fields (CMP) u Project: ITSOBank u Package: itso.bank.ejb u Class: CustomerBean u Superclass: itso.bank.ejb.base.ITSOEntityBean u EJB Home Interface: CustomerHome u EJB Remote Interface: Customer u EJB Key Class or Field: CustomerKey u import statements:

itso.bank.ejb.base.* itso.bank.ejb.relation.* itso.bank.ejb.inheritance.relation.*

Add Fields
CMP
For directions on how to add CMP fields see , Adding fields to the Bean on page 122. We need to add six fields with the same characteristics. Only the name of the field is different. Use the information given in Table 12, but changing Field Name accordingly, to create the following fields :
u bankForeignkey u firstName u lastName u password u title

290

Developing Enterprise JavaBeans with VisualAge for Java

u userid

Table 12. Create Fields for the Customer Bean


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

bankForeignKey
String public none checked

public public yes

Transient
We create two transient fields required to implement the associations between:
u Customer and Bank (SingleLink) u Customer and BankAccount (BankAccountManyLink)

Table 13. Create Field bankAccountLink


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter bankAccountLink itso.bank.ejb.inheritance.relation.BankAccountManyLink private transient checked

private (none)

Bank Implementation Entity Beans

291

Table 13. Create Field bankAccountLink


Field Name Container Managed bankAccountLink no

Table 14. Create Field bank


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed bank itso.bank.ejb.relation.SingleLink private transient checked

public (none) no

Add new methods


For directions on how to add a method to an EJB see , Adding methods to EJBs on page 41.
u addBankAccount public void addBankAccount(BankAccount bankAccount) throws java.rmi.RemoteException { getBankAccountLink().addBankAccount(bankAccount); } u getBankAccounts public Enumeration getBankAccounts() throws java.rmi.RemoteException { return getBankAccountLink().getBankAccounts(); } u getBankLink private SingleLink getBankLink() throws java.rmi.RemoteException { if (bank == null)

292

Developing Enterprise JavaBeans with VisualAge for Java

bank = new SingleLink(this, "Bank", "itso.bank.ejb", "bankForeignKey", "primaryKey"); return bank; } u getCustomerId public String getCustomerId() { return primaryKey; } u removeBankAccount public void removeBankAccount(BankAccount bankAccount) throws java.rmi.RemoteException { getBankAccountLink().removeBankAccount(bankAccount); }

Modify the Generated Methods


u ejbActivate public void ejbActivate() throws java.rmi.RemoteException { super.ejbActivate(); traceMethod("ejbActivate()"); } u ejbCreate public void ejbCreate(CustomerKey customerKey, String customerTitle, String customerFirstName, String customerLastName, String customerUserid, String customerPassword, Bank bank) throws RemoteException { try { super.ejbCreate(); primaryKey = customerKey.primaryKey; title = customerTitle; firstName = customerFirstName; lastName = customerLastName; userid = customerUserid; password = customerPassword; getBankLink().setValue(bank); //sets only foreign key => foreign key is defined NOT NULL in the database } catch(Exception e) { throw wrapperNonRemoteException("CustomerBean.ejbCreate(CustomerKey, String, String, String, Bank)", e); } traceMethod("ejbCreate(CustomerKey customerKey, String customerTitle, String customerFirstName, String customerLastName, Bank bank");

Bank Implementation Entity Beans

293

} u ejbLoad public void ejbLoad () throws java.rmi.RemoteException { super.ejbLoad(); getBankLink().setUninitialized(); getBankAccountLink().setUninitialized(); traceMethod("ejbLoad()"); } u ejbPassivate public void ejbPassivate() throws java.rmi.RemoteException { super.ejbPassivate(); traceMethod("ejbPassivate()"); } u ejbPostCreate public void ejbPostCreate(CustomerKey customerKey, String customerTitle, String customerFirstName, String customerLastName, String customerUserid, String customerPassword, Bank bank) throws RemoteException { super.ejbPostCreate(); getBankLink().setValue(bank); //updates the object relation traceMethod("ejbPostCreate(CustomerKey customerKey, String customerFirstName, String customerLastName, Bank bank"); } u ejbRemove public void ejbRemove() throws java.rmi.RemoteException { super.ejbRemove(); bank.setValue(null); getBankAccountLink().removeAllMembers(); traceMethod("ejbRemove()"); } u ejbStore public void ejbStore () throws java.rmi.RemoteException { //bankId = getBankRelation().getBankId(); super.ejbStore(); traceMethod("CustomerBean.ejbStore()"); } u setEntityContext public void setEntityContext(EntityContext ctx) throws java.rmi.RemoteException { super.setEntityContext(ctx); traceMethod("setEntityContext(EntityContext)"); }

294

Developing Enterprise JavaBeans with VisualAge for Java

u unsetEntityContext public void unsetEntityContext() throws java.rmi.RemoteException { super.unsetEntityContext(); traceMethod("unsetEntityContext()"); }

Add Methods to the Remote Interface


Select the following methods and add them to the bean remote interface. For directions on how to add a method to the remote interface, see , Adding Methods to the Remote Interface on page 46.
u getBank u getBankAccounts u getCustomerId u getFirstName u getLastName u getTitle u removeBankAccount u setFirstName u setLastName u setTitle

Adding Finder Methods to CustomerHome


We need to add extra finder methods to the customer home:
u findByBankId u findByUserId

In addition to adding these methods to the CustomerHome, you need to modify the CustomerBeanFinderHelper as indicated below:
public interface CustomerBeanFinderHelper { public static final String findByBankIdQueryString = "SELECT T1.TITLE, T1.CUSTID, T1.PASSWORD, T1.FNAME, T1.USERID, T1.BANKID, T1.LNAME FROM ITSO.CUSTOMER T1 WHERE T1.BANKID = ?"; public static final String findByUserIdQueryString = "SELECT T1.TITLE, T1.CUSTID, T1.PASSWORD, T1.FNAME, T1.USERID, T1.BANKID, T1.LNAME FROM ITSO.CUSTOMER T1 WHERE T1.USERID = ? AND T1.PASSWORD = ?"; }

Bank Implementation Entity Beans

295

For additional information about how to add finder methods see 4.9, Adding Special Finder methods on page 160.

12.4 Developing the TransactionRecord Entity Bean


Create a new transactionRecord bean in the ITSOBank group specifying the following information:
u Bean name: TransactionRecord u Bean type: Entity bean with container-managed fields (CMP) u Project: ITSOBank u Package: itso.bank.ejb u Class: TransactionRecordBean u Superclass: itso.bank.ejb.base.ITSOEntityBean u EJB Home Interface: TransactionRecordHome u EJB Remote Interface: TransactionRecord u EJB Key Class or Field: TransactionRecordKey u import statements:

itso.bank.ejb.base.* itso.bank.ejb.relation.* itso.bank.ejb.inheritance.relation.*

Add Fields
CMP
For directions on how to add CMP fields see , Adding fields to the Bean on page 122. We need to add two fields with the same characteristics. Only the name of the field is different. Use the information given in Table 15, but changing Field Name accordingly, to create the following fields :
u accountId u traccId

296

Developing Enterprise JavaBeans with VisualAge for Java

Table 15. Create Field accountId and traccId


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

accountId
String public none unchecked

public public yes

Table 16. Create Field transamt


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

transamt
java.math.BigDecimal public none checked

public public yes

Table 17. Create Field transamt


Field Name Filed Type

transtype
String

Bank Implementation Entity Beans

297

Table 17. Create Field transamt


Field Name Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

transtype
public none checked

public (none) yes

Transient
Table 18. Create Field accountLink
Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed accountLink itso.bank.ejb.inheritance.relation.BankAccountSingleLink private transient checked

private (none) no

Add new methods


For directions on how to add a method to an EJB see , Adding methods to EJBs on page 41.

298

Developing Enterprise JavaBeans with VisualAge for Java

u getBankAccount public BankAccount getBankAccount() throws java.rmi.RemoteException { return getAccountLink().getBankAccount(); } u getTransactingAccount public BankAccount getTransactingAccount() throws java.rmi.RemoteException { //this.traccId = ((BankAccountKey) otherAccount.getPrimaryKey()).accountId; if (traccId == null) { return null; } try { BankAccount account = itso.bank.ejb.inheritance.relation.TypeConverter.getBankAccountHome().findByPri maryKey( new BankAccountKey(traccId)); return itso.bank.ejb.inheritance.relation.TypeConverter.typeCast(account); } catch (Exception exc) { throw new RemoteException(exc.getMessage()); } } u getTransactionID public java.sql.Timestamp getTransactionID() throws java.rmi.RemoteException{ return primaryKey; } u setTransactingAccount public void setTransactingAccount(BankAccount otherAccount) throws java.rmi.RemoteException { this.traccId = ((BankAccountKey) otherAccount.getPrimaryKey()).accountId; }

Modify the Generated Methods


u ejbActivate public void ejbActivate() throws java.rmi.RemoteException { super.ejbActivate(); } u ejbCreate public void ejbCreate(TransactionRecordKey key, BankAccount account, java.math.BigDecimal amount, String transType) throws RemoteException { super.ejbCreate(); // All CMP fields should be intialized here.

Bank Implementation Entity Beans

299

primaryKey = key.primaryKey; this.transamt = amount; this.transtype = transType; getAccountLink().setValue(account); } u ejbLoad public void ejbLoad () throws java.rmi.RemoteException { super.ejbLoad(); } u ejbPassivate public void ejbPassivate() throws java.rmi.RemoteException { super.ejbPassivate(); } u ejbPostCreate public void ejbPostCreate(TransactionRecordKey key, BankAccount account, java.math.BigDecimal amount, String transType) throws RemoteException { super.ejbPostCreate(); // All CMP fields should be intialized here. getAccountLink().setValue(account); } u ejbRemove public void ejbRemove() throws java.rmi.RemoteException { super.ejbRemove(); getAccountLink().setValue(null); } u ejbStore public void ejbStore () throws java.rmi.RemoteException { super.ejbStore(); } u setEntityContext public void setEntityContext(javax.ejb.EntityContext ctx) throws java.rmi.RemoteException { super.setEntityContext(ctx); } u unsetEntityContext public void unsetEntityContext() throws java.rmi.RemoteException { super.unsetEntityContext(); }

300

Developing Enterprise JavaBeans with VisualAge for Java

Add Methods to the Remote Interface


Select the following methods and add them to the bean remote interface. For directions on how to add a method to the remote interface, see , Adding Methods to the Remote Interface on page 46.
u getBankAccount u getTransactingAccount u getTransactionID u getTransamt u getTranstype u setTransamt

Adding Finder Method to TransactionRecordHome


We need to add extra finder method to the TransactionRecord home:
u findByAccountId

In addition to adding these methods to the TransactionRecordHome, you need to modify the TransactionRecordBeanFinderHelper as indicated below:
public interface TransactionRecordBeanFinderHelper { public static final String findByAccountIdQueryString = "SELECT T1.TRANSID, T1.TRANSTYPE, T1.TRANSAMT, T1.ACCID, T1.TRACCID FROM ITSO.TRANSRECORD T1 WHERE T1.ACCID = ?"; }

For additional information about how to add finder methods see 4.9, Adding Special Finder methods on page 160.

12.5 Creating the Bank Schemas


In the bank application we use Container-managed persistence beans. Normally, a bean developer does not need to specify how the beans field are mapped to a given persistent store. This is the deployer role. Remember that VisualAge for Java, in addition to a complete Enterprise JavaBeans development environment, also provides deployment and test facilities.

Bank Implementation Entity Beans

301

We use these additional capabilities to create the Container-managed persistence field mapping to a persistent store. For our bank application, the persistent store is based on an existing database called ITSOBANK. Details about the definition of the ITSOBANK database can be found in Appendix C, ITSOBANK database on page 365. For directions on how to create a schema see , Importing a database schema into VisualAge for Java on page 148. In order to create this schema, you need to provide the following information:

Table 19. Create Bank Schema


Enter the name for the schema Database Connection type Database Connection Data source Select Tables Qualifiers Tables Bank COM.ibm.db2.jdbc.app.Db2Driver jdbc:db2:ITSOBANK

ITSO select them all

The next step consist in using the schema to create a datastore map.

12.6 Creating the Bank Maps


For directions on how to create a schema see , Defining a map between the EJBs and the database schema on page 153. For the creation of this map you need the following information:

Table 20. Create Bank Datastore Map


New Datastore Map Name New Datastore Map EJB group Bank ITSOBank

302

Developing Enterprise JavaBeans with VisualAge for Java

In the Map browser, you need to specify for each Persistent Classes the corresponding Table Maps as described hereafter: Table 21. Bank Table Maps
Persistent Classes Bank BankAccount CheckingAccount CorporateAccount Customer SavingsAccount TransactionRecord Table Maps BANK ACCOUNT CHECKING PAYEE CUSTOMER SAVINGS TRANSRECORD

For each Table Maps item, you indicate the relationship between the class attribute and a table column. In addition, you also give the map type as follows: Table 22. Bank Property Map Relationship
Persistent Classes Bank Class Attribute primaryKey bankName BankAccount accountId accountType balance customerFK bankFK CheckingAccount overdraft accountId CorporateAccount billPaymentTitle accounId SavingAccount accountId minAmount Map Type Simple Simple Simple Simple Simple Simple Simple Simple Simple Simple Simple Simple Simple Table Column BANKID BANKNAME ACCID ACCTYPE BALANCE CUSTID BANKID OVERDRAF ACCID TITLE ACCID ACCID MINAMT

Bank Implementation Entity Beans

303

Persistent Classes Customer

Class Attribute title primaryKey firstName password userid bankForeignKey lastName

Map Type Simple Simple Simple Simple Simple Simple Simple Simple Simple Simple Simple Simple

Table Column TITLE CUSTID FNAME PASSWORD USERID BANKID LNAME ACCID TRANSAMT TRANSTYPE TRANSID TRACCID

TransactionRecord

accounId transamt transtype primaryKey traccId

We have finished with the implementation of the bank application entity beans. Another part of the business logic is implemented as session beans. We have defined a UserSB which implements customer use cases and an AdminSB which implements administrative use cases. These two session beans are the subjects of the following chapters.

304

Developing Enterprise JavaBeans with VisualAge for Java

13 Bank implementation UserSB


In this chapter we describe the UserSB session bean which implements all use cases as seen by the end user. Customers use the home banking application to perform a set of banking operations from home through the Internet. This application includes making funds transfers, checking account balances, paying bills and more. It addresses three kinds of accounts: checking, savings and payee. Checking accounts are used to manage current expenses, savings accounts are used to manage your personal savings and payee accounts are used to manage the corporations you pay bills to. All possible operations are described by sequence diagrams in the following sections.

Copyright IBM Corp. 1999

305

13.1 The UserSB sequence diagrams


To better illustrate the interactions between UserSB and its client, we provide the corresponding sequence diagrams.

UserSB Customer Authentication Sequence Diagram


Before a user can start using any secured system, he is always asked to identify and authenticate himself. For that purpose, the client application of our bank application, needs first to create an instance of UserSB and then invoke the authenticate method (for information about how to create a session bean can be found in Chapter , Instantiating a Beans EJB object on page 71).

306

Developing Enterprise JavaBeans with VisualAge for Java

Figure 140. UserSB Customer Authentication Sequence Diagram

The authenticate method uses a user defined finder method on the CustomerHome in order to get an enumeration of customers with the same userId. Since each userid is unique only one customer should be returned. Once the customer is found we store the customerLogin password and object reference for later use.

Bank implementation UserSB

307

UserSB Customer GetAccounts Sequence Diagram


When the client asks for the list of the accounts, the getAccounts method delegates the request to the customer object by invoking getBankAccountas shown in Figure 141. The getAccounts() method returns an array of data used by the client for display purpose only. In this case we return the accountId and the accountType description for each account.

Figure 141. UserSB GetAccounts Sequence Diagram

308

Developing Enterprise JavaBeans with VisualAge for Java

UserSB Customer Deposit Sequence Diagram


Once the client gets the list of accounts he can perform usual bank operations. This comes down for the UserSB to find the corresponding BankAccount instance from the BankAccountHome idenitfied by its key. For information about how to build the key refer to, Working with the key Class on page 130. We do not include the steps for creating the keys in the sequence diagram because of lack of space but of course you need to create a key first. As you can see from figure Figure 142 the deposit business action is delegated to the BankAccount object while the UserSB is responsible to create the TransactionRecord associated to this bank transaction.

Figure 142. UserSB Deposit Sequence Diagram

Bank implementation UserSB

309

UserSB Customer Withdraw Sequence Diagram


The flow here is very similar to the one of the deposit action.

Figure 143. UserSB Withdraw Sequence Diagram

UserSB Customer GetBalance Sequence Diagram


The GetBalance sequence diagram is very simple. When the UserSB receives the getBalance request from the client it asks to the BankAccontHome to find the right BankAccount corresponding to the specified key. Then it invokes the getBalance() method on the BankAccount instance.

310

Developing Enterprise JavaBeans with VisualAge for Java

Figure 144. UserSB getBalance Sequence Diagram

UserSB Customer GetHistory Sequence Diagram


The client can select an account and ask for the account history by specifying a starting and an ending date. For example the customer wants to see all the account movement starting form March 1st, 1999 until March 12, 1999. UserSB looks for the right account reference. It invokes getTransactionRecords method and performs a filtering operation based on the given starting and ending dates before returning the result.

Bank implementation UserSB

311

Figure 145. UserSB getHistory Sequence Diagram

UserSB Customer Transfer Sequence Diagram


So far, most of the services provided by the UserSB, result in delegating the operation to a single entity bean. With the transfer method, the use of a session bean makes more sense. It implements the logic to deal with several entity beans.

312

Developing Enterprise JavaBeans with VisualAge for Java

Figure 146. UserSB transfer Sequence Diagram

UserSB Customer PayBill Sequence Diagram


The payBill action implies two BankAccounts: the source (the customer account) and the target (the payee account). For example the customer wants to pay a phone bill to the phone company. To authorize a payBill action we need to authentify the customer. You can see from the sequence diagram in Figure 147 that the payBill action is actually a transfer where the target account is always a payee account.

Bank implementation UserSB

313

Figure 147. UserSB PayBill Sequence Diagram

Now we are ready to develop the UserSB.

13.2 Creating the UserSB Session Bean


UserSB is a stateful session bean because it maintains the customer login status information. We assume that now you are familiar with the environment and skip on purpose some details in the following steps: 1. Start VisualAge for Java. 2. Select the ITSOBank project. 3. Create a new package called itso.bank.ejb.sb.user. 4. Create a new EJB called UserSB in the ITSOBank EJB group. Use itso.bank.ejb.sb.user as package name. 5. Once the UserSB is created, go to the Properties and select STATEFUL in the State Management Attribute combo box. 6. Select the UserSBBean class and add the following import statements:
import itso.bank.ejb.*;

314

Developing Enterprise JavaBeans with VisualAge for Java

import itso.bank.ejb.base.*; import itso.bank.ejb.relation.*; import itso.bank.ejb.inheritance.relation.*;

7. The UserSB declaration should look like this:


public class UserSBBean extends ITSOSessionBean implements javax.ejb.SessionBean

We

extend

from

ITSOSessionBean

which

extends

itself

from

itso.bank.ejb.base.ITSOEnterpriseBean. This upper class with the help of

Homefactory class manage to find and caches the homes. In this way we save the processing time to go to the naming services and find the homes. 8. Modify the State Management Attribute to #STATEFUL

Figure 148. Properties for the UserSB

Add Fields
The UserSB session bean needs to maintain some information like the login password. We also need values like the reference to the customer who logs in. In this way we do not have to get it everytime we need because since the UserSB is alive it will be tied to that particular customer session.

Bank implementation UserSB

315

We also cache the Home objects for all the classes involved in our use case. In this way we avoid to do a lookup each time we need to deal with a class we have already used.

Table 23. Create Field bankAccountHome


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

bankAccountHome
itso.bank.ejb.BankAccountHome private none checked

private (none) no

Table 24. Create Field bankHome


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

bankHome
itso.bank.ejb.BankAccountHome private none checked

private (none) no

316

Developing Enterprise JavaBeans with VisualAge for Java

Table 25. Create Field custKey


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

custKey
itso.bank.ejb.CustomerKey private none checked

private private no

Table 26. Create Field customerHome


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

customerHome
itso.bank.ejb.CustomerHome private none checked

private private no

Bank implementation UserSB

317

Table 27. Create Field customerRef


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

customerRef
itso.bank.ejb.Customer private none checked

private private no

Table 28. Create Field initialCtx


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

initialCtx
javax.naming.Context private none checked

private private no

318

Developing Enterprise JavaBeans with VisualAge for Java

Table 29. Create Field loginPassword


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

loginPassword
String private none checked

private private no

Table 30. Create Field loginStatus


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

loginStatus
boolean private none checked

private private no

Table 31. Create Field transactionRecordHome


Field Name Filed Type

transactionRecordHome
itso.bank.ejb.TransactionHome

Bank implementation UserSB

319

Table 31. Create Field transactionRecordHome


Field Name Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter Container Managed

transactionRecordHome
private none checked

private private no

Add New Methods


For directions on how to add a method to an EJB see , Adding methods to EJBs on page 41.
u authenticate public boolean authenticate(String user, String password) throws java.rmi.RemoteException { Customer tempCust = null; CustomerHome custHome = getCustomerHome(); java.util.Enumeration custList = null; int numberElements = 0; try { custList = custHome.findByUserId(user, password); } catch (javax.ejb.FinderException e) { // Wrong userId and/or bad password, authentication failed setLoginState(false); return loginStatus; } while (custList.hasMoreElements()) { numberElements++; tempCust = (Customer)custList.nextElement(); } if (numberElements > 1) { // More than one customer record exist in the database with this user id and password // Authentication failed setLoginState(false); return loginStatus; } else if (numberElements == 0) {

320

Developing Enterprise JavaBeans with VisualAge for Java

// Enumeration is empty, no Customer found setLoginState(false); return loginStatus; } // User Id and password are valid, authentication is OK. Now we need to check // if only one instance has been returned from the database setLoginState(true); loginPassword = password; setCustomerRef(tempCust); return getLoginState(); } u buildBankAccountHome private void buildBankAccountHome() throws java.rmi.RemoteException { bankAccountHome = (BankAccountHome) getHome("BankAccount"); } u buildBankHome private void buildBankHome() throws RemoteException { bankHome = (BankHome) getHome("Bank"); } u buildCustomerHome private void buildCustomerHome() throws RemoteException { customerHome = (CustomerHome) getHome("Customer"); } u buildTransactionRecordHome private void buildTransactionRecordHome() throws java.rmi.RemoteException { transactionRecordHome = (TransactionRecordHome) getHome("TransactionRecord"); } u deposit public void deposit(String accId,java.math.BigDecimal amt) { TransactionRecordKey txKey = null; // Get the home interface try { // Create the BankAccountKey from the ID BankAccountKey bAcKey = new BankAccountKey(accId); //Find the right BankAccount instance with from the key BankAccount account=TypeConverter.typeCast(getBankAccountHome().findByPrimaryKey(bAcKey)); //call the deposit method on the account account.deposit(amt); // Since the deposit action is a transaction made on the account we need to create a TransactionRecord

Bank implementation UserSB

321

// and store i in the DataBase. TransactionRecordHome trHome = (TransactionRecordHome)getHome("TransactionRecord"); try { // Now that the withdraw has been processed we need to create an instance of TransactionRecord java.sql.Timestamp transId = new java.sql.Timestamp(System.currentTimeMillis()); txKey = new TransactionRecordKey(transId); TransactionRecord newRecord = trHome.create(txKey, account, amt,"C"); } catch (javax.ejb.CreateException e) { // setRollbackFlag(); } } catch (BankTransactionException e1) { System.out.println(e1.getMessage()); // setRollbackFlag(); } catch (Exception e) { e.printStackTrace(System.out); }// endtry } u getBalance public java.math.BigDecimal getBalance( String accountId) { try { //this is only needed for testing. BankAccountKey bAcKey = new BankAccountKey(accountId); BankAccount account= TypeConverter.typeCast(getBankAccountHome().findByPrimaryKey(bAcKey)); return account.getBalance(); } catch(Exception except) { except.printStackTrace(System.out); //throw wrapperNonRemoteException("UserSB.getCustomer(String)", except); return null; } } u getCustomer public Customer getCustomer(String customerId) throws RemoteException { CustomerHome cHome =null; try { //this is only needed for testing. CustomerKey cKey = new CustomerKey(customerId);

322

Developing Enterprise JavaBeans with VisualAge for Java

setCustomerRef(getCustomerHome().findByPrimaryKey(cKey)); return (customerRef); } catch(Exception except) { except.printStackTrace(System.out); //throw wrapperNonRemoteException("UserSB.getCustomer(String)", except); return null; } } u getHistory public String[][] getHistory(String accId,java.util.Date startDate,java.util.Date endDate,String type) { // Get the home interface for the Bank Account TransactionRecordHome trHome =null; try { // Create the BankAccountKey from the ID BankAccountKey bAcKey = new BankAccountKey(accId); //Find the right BankAcount instance with from the key BankAccount account= TypeConverter.typeCast(getBankAccountHome().findByPrimaryKey(bAcKey)); // Vector to contain the right transaction to return java.util.Vector v = new java.util.Vector(); //call the getTransactionRecords to get all tasaction related to this account java.util.Enumeration transEnum = account.getTransactionRecords(); while(transEnum.hasMoreElements()) { TransactionRecord tRecord = (TransactionRecord)transEnum.nextElement(); if( startDate != null){ if(((java.util.Date)(tRecord.getTransactionID())).before( startDate)){ continue; } } if( endDate != null){ if(((java.util.Date)(tRecord.getTransactionID())).after( endDate)){ continue; } } if( type != null){ if( !(type.equals( tRecord.getTranstype()))){ continue; } } v.addElement( tRecord); } String[][]transDataArray = new String[v.size()][3]; if( v.size() > 0){

Bank implementation UserSB

323

for( int i = 0; i < v.size(); i++){ transDataArray[i][0]=((java.util.Date)(((TransactionRecord)(v.elementAt(i))).getTransactionID())) .toString(); transDataArray[i][1]= (((TransactionRecord)(v.elementAt(i))).getTranstype()); transDataArray[i][2]= (((TransactionRecord)(v.elementAt(i))).getTransamt()).toString(); } } return transDataArray ; } /*********/ catch(Exception except) { except.printStackTrace(System.out); return null; } } u paybill public void paybill(String source, String destination, java.math.BigDecimal amount, String password) throws java.rmi.RemoteException { // CustomerHome custHome = getCustomerHome(); BankAccountKey keyObject = null; // First, we need to verify the validity of the password if (!(password.equals(this.loginPassword))) { // throw new BankException(); } else // Proceed with the transfer transfer(source, destination, amount); } u transfer public void transfer(String source, String destination, java.math.BigDecimal amount) throws java.rmi.RemoteException { BankAccountHome bankAccountHome = getBankAccountHome(); TransactionRecordHome trxHome = getTransactionRecordHome(); BankAccountKey sourceKeyObject = null; BankAccountKey destKeyObject = null; TransactionRecordKey txKey = null; try { sourceKeyObject = new BankAccountKey(source);

324

Developing Enterprise JavaBeans with VisualAge for Java

BankAccount sourceAccount = TypeConverter.typeCast(bankAccountHome.findByPrimaryKey(sourceKeyObject)); destKeyObject = new BankAccountKey(destination); BankAccount targetAccount = TypeConverter.typeCast(bankAccountHome.findByPrimaryKey(destKeyObject)); // Use the next line with inheritance implemented sourceAccount.withdraw(amount); // Use the next block if no inheritance is implemented (Using one object and one table) sourceAccount.withdraw(amount, sourceAccount.getAccountType()); try { // Now that the withdraw has been processed we need to create an instance of TransactionRecord java.sql.Timestamp transId = new java.sql.Timestamp(System.currentTimeMillis()); txKey = new TransactionRecordKey(transId); TransactionRecord newRecord = trxHome.create(txKey, sourceAccount, amount,"T"); newRecord.setTransactingAccount(targetAccount); } catch (javax.ejb.CreateException e) { // setRollbackFlag(); } targetAccount.deposit(amount); try { // Now that the withdraw has been processed we need to create an instance of TransactionRecord java.sql.Timestamp transId = new java.sql.Timestamp(System.currentTimeMillis()); txKey = new TransactionRecordKey(transId); TransactionRecord newRecord = trxHome.create(txKey, targetAccount, amount,"F"); newRecord.setTransactingAccount(sourceAccount); } catch (javax.ejb.CreateException e) { // setRollbackFlag(); } } catch (FinderException e) { // setRollbackFlag(); } catch (BankTransactionException e1) { System.out.println(e1.getMessage()); // setRollbackFlag(); } catch (Exception ex) { System.out.println(ex.getMessage()); } // } u withdraw public void withdraw(String account, java.math.BigDecimal amount) throws java.rmi.RemoteException { BankAccountHome bankAccountHome = getBankAccountHome();

Bank implementation UserSB

325

TransactionRecordHome trxHome = getTransactionRecordHome(); BankAccountKey keyObject = null; TransactionRecordKey txKey = null; try { keyObject = new BankAccountKey(account); BankAccount sourceAccount = TypeConverter.typeCast( bankAccountHome.findByPrimaryKey(keyObject) ); // Use the next line with inheritance implemented sourceAccount.withdraw(amount); // Use the next block if no inheritance is implemented (Using one object and one table) // sourceAccount.withdraw(amount, sourceAccount.getAccountType()); try { // Now that the withdraw has been processed we need to create an instance of TransactionRecord java.sql.Timestamp transId = new java.sql.Timestamp(System.currentTimeMillis()); txKey = new TransactionRecordKey(transId); TransactionRecord newRecord = trxHome.create(txKey, sourceAccount, amount, "D"); } catch (javax.ejb.CreateException e) { // setRollbackFlag(); } } catch (FinderException e) { // setRollbackFlag(); } catch (BankTransactionException e1) { System.out.println(e1.getMessage()); // setRollbackFlag(); } }

Modify the Generated Methods


u getBank private Bank getBank(String bankId) throws RemoteException { try { return getBankHome().findByPrimaryKey(new BankKey(bankId)); } catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getBank(String)", except); } } u getBankHome private BankHome getBankHome() throws RemoteException { if (bankHome == null)

326

Developing Enterprise JavaBeans with VisualAge for Java

buildBankHome(); return bankHome; } u getCheckingAccount private CheckingAccount getCheckingAccount(String bankingAccountId) throws RemoteException { try { return getCheckingAccountHome().findByPrimaryKey(new BankAccountKey(bankingAccountId)); } catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getCheckingAccount(String bankingAccountId)", except); } } u getCheckingAccountHome private CheckingAccountHome getCheckingAccountHome() throws RemoteException { if (checkingAccountHome == null) buildCheckingAccountHome(); return checkingAccountHome; } u getCorporateAccount private CorporateAccount getCorporateAccount(String bankingAccountId) throws RemoteException { try { return getCorporateAccountHome().findByPrimaryKey(new BankAccountKey(bankingAccountId)); } catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getCorporateAccount(String bankingAccountId)", except); } } u getCorporateAccountHome private CorporateAccountHome getCorporateAccountHome() throws RemoteException { if (corporateAccountHome == null) buildCorporateAccountHome(); return corporateAccountHome; } u getCustomer private Customer getCustomer(String customerId) throws RemoteException { try { return getCustomerHome().findByPrimaryKey(new CustomerKey(customerId)); }

Bank implementation UserSB

327

catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getCustomer(String)", except); } } u getCustomerHome private CustomerHome getCustomerHome() throws RemoteException { if (customerHome == null) buildCustomerHome(); return customerHome; } u getSavingsAccount private SavingsAccount getSavingsAccount(String bankingAccountId) throws RemoteException { try { return getSavingsAccountHome().findByPrimaryKey(new BankAccountKey(bankingAccountId)); } catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getSavingsAccount(String bankingAccountId)", except); } } u getSavingsAccountHome private SavingsAccountHome getSavingsAccountHome() throws RemoteException { if (savingsAccountHome == null) buildSavingsAccountHome(); return savingsAccountHome; }

Add Methods to the Remote Interface


Select the following methods and add them to the bean remote interface. For directions on how to add a method to the remote interface, see , Adding Methods to the Remote Interface on page 46.
u createBank u createCheckingAccount u createCorporateAccount u createCustomer u createSavingsAccount u deleteBank u deleteCheckingAccount

328

Developing Enterprise JavaBeans with VisualAge for Java

u deleteCorporateAccount u deleteCustomer u deleteSavingsAccount

Generate Deployed Code


Once you are done you can generate the deployed code. You may notice that in addition to the classes generated so far (see Generating Deployed Code on page 47) there are some new classes in the Types panes.

Figure 149. UserSB generetaed code.

The StringX?ArrayHelper and the StringX?ArrayHolder have been generated because we have used arrays of string as return type for getAccounts and getHistory methods. These classes are used to marshal the arrays before sending them through the ORB. The UserSB is now ready for use by a client application. You can also use the test client to verify the behavior of the UserSB (See Running the Generated

Bank implementation UserSB

329

Test Client on page 64.) You need to start with the first business method: authenticate.

330

Developing Enterprise JavaBeans with VisualAge for Java

14 Bank Implementation AdminSB


As we have explained in previous chapters, the bank application implementation covers two different aspects: user and administration interactions. In this chapter, we look to the administration part. The session bean AdminSB offers to client applications a set of methods based on use cases required to manage the bank.

14.1 Developing the AdminSB Session Bean


Create a new AdminSB session bean in the ITSOBank group specifying the following information:
u Bean name: AdminSB

Copyright IBM Corp. 1999

331

u Bean type: Session Bean) u Project: ITSOBank u Package: itso.bank.ejb.sb.admin u Class: AdminSBBean u Superclass: itso.bank.ejb.base.ITSOSessionBeanEJB u Home Interface: AdminSBHome u EJB Remote Interface: AdminSB u EJB Key Class or Field: none u import statements:

itso.bank.ejb.* itso.bank.ejb.base.*

Add Fields
The AdminSB requires the creation of the following fields:
u customerHome u bankHome u savingsAccountHome u checkingAccountHome u checkingAccountHome

with the same characteristics as given in Table 32.

Table 32. Create Field for AdminSB


Field Name Filed Type Access Modifiers Other Modifiers Access with getter and setter methods Getter Setter (see list above for the appropriate name) itso.bank.ejb private transient checked

private (none)

332

Developing Enterprise JavaBeans with VisualAge for Java

Table 32. Create Field for AdminSB


Field Name Container Managed (see list above for the appropriate name) no

Add new methods


u getBank private Bank getBank(String bankId) throws RemoteException { try { return getBankHome().findByPrimaryKey(new BankKey(bankId)); } catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getBank(String)", except); } } u getCheckingAccount private CheckingAccount getCheckingAccount(String bankingAccountId) throws RemoteException { try { return getCheckingAccountHome().findByPrimaryKey(new BankAccountKey(bankingAccountId)); } catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getCheckingAccount(String bankingAccountId)", except); } } u getCorporateAccount private CorporateAccount getCorporateAccount(String bankingAccountId) throws RemoteException { try { return getCorporateAccountHome().findByPrimaryKey(new BankAccountKey(bankingAccountId)); } catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getCorporateAccount(String bankingAccountId)", except); } }

Bank Implementation AdminSB

333

u getCustomer private Customer getCustomer(String customerId) throws RemoteException { try { return getCustomerHome().findByPrimaryKey(new CustomerKey(customerId)); } catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getCustomer(String)", except); } } u getSavingsAccount private SavingsAccount getSavingsAccount(String bankingAccountId) throws RemoteException { try { return getSavingsAccountHome().findByPrimaryKey(new BankAccountKey(bankingAccountId)); } catch(Exception except) { throw wrapperNonRemoteException("UseCaseSB.getSavingsAccount(String bankingAccountId)", except); } } u buildBankHome private void buildBankHome() throws RemoteException { bankHome = (BankHome) getHome("Bank"); } u buildCheckingAccountHome private void buildCheckingAccountHome() throws RemoteException { checkingAccountHome = (CheckingAccountHome) getHome("CheckingAccount"); } u buildCorporateAccountHome private void buildCorporateAccountHome() throws RemoteException { corporateAccountHome = (CorporateAccountHome) getHome("CorporateAccount"); } u buildCustomerHome private void buildCustomerHome() throws RemoteException { customerHome = (CustomerHome) getHome("Customer"); } u buildSavingsAccountHome private void buildSavingsAccountHome() throws RemoteException { savingsAccountHome = (SavingsAccountHome) getHome("SavingsAccount");

334

Developing Enterprise JavaBeans with VisualAge for Java

} u createBank public void createBank(String bankId, String bankName) throws java.rmi.RemoteException { try { getBankHome().create(new BankKey(bankId), bankName); } catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.createBank(String bankId, String bankName)", e); } } u createCheckingAccount public void createCheckingAccount(String accountId, String customerId, BigDecimal overdraftLimit) throws java.rmi.RemoteException { try { Customer customerOfCheckingAccount = getCustomer(customerId); Bank bankOfCustomer = customerOfCheckingAccount.getBank(); CheckingAccount newCheckingAccount = getCheckingAccountHome().create(new BankAccountKey(accountId), customerOfCheckingAccount, bankOfCustomer); newCheckingAccount.setOverDraftLimit(overdraftLimit); } catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.createCheckingAccount(String accountId, String customerId, BigDecimal overdraftLimit)", e); } } u createCorporateAccount public void createCorporateAccount(String accountId, String customerId, String billPaymentTitle) throws java.rmi.RemoteException { try { Customer customerOfCorporateAccount = getCustomer(customerId); Bank bankOfCustomer = customerOfCorporateAccount.getBank(); CorporateAccount newCorporateAccount = getCorporateAccountHome().create(new BankAccountKey(accountId), customerOfCorporateAccount, bankOfCustomer); newCorporateAccount.setBillPaymentTitle(billPaymentTitle); } catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.createCorporateAccount(String accountId, String customerId, String billPaymentTitle)", e); } }

Bank Implementation AdminSB

335

u createCustomer public void createCustomer(String customerId, String customerTitle, String customerFirstName, String customerLastName, String customerUserid, String customerPassword, String bankId) throws RemoteException { try { Customer newCustomer = null; Bank bankOfCustomer = getBank(bankId); newCustomer = getCustomerHome().create(new CustomerKey(customerId), customerTitle, customerFirstName, customerLastName, customerUserid, customerPassword, bankOfCustomer); } catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.createCustomer(String customerId, String customerTitle, String customerFirstName, String customerLastName, String customerUserid, String customerPassword, String bankId)", e); } } u createSavingsAccount public void createSavingsAccount(String accountId, String customerId, BigDecimal minimumBalance) throws java.rmi.RemoteException { try { Customer customerOfSavingsAccount = getCustomer(customerId); Bank bankOfCustomer = customerOfSavingsAccount.getBank(); SavingsAccount newSavingsAccount = getSavingsAccountHome().create(new BankAccountKey(accountId), customerOfSavingsAccount, bankOfCustomer); newSavingsAccount.setMinimumBalance(minimumBalance); } catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.createSavingsAccount(String accountId, String customerId, BigDecimal minimumBalance)", e); } } u deleteBank public void deleteBank(String bankId) throws java.rmi.RemoteException { try { Bank bankToDelete = getBank(bankId); bankToDelete.remove(); } catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.deleteBank(String bankId)", e); } }

336

Developing Enterprise JavaBeans with VisualAge for Java

u deleteCheckingAccount public void deleteCheckingAccount(String bankAccountId) throws java.rmi.RemoteException { try { CheckingAccount checkingAccountToDelete = getCheckingAccount(bankAccountId); checkingAccountToDelete.remove(); } catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.deleteCheckingAccount(String bankAccountId)", e); } } u deleteCorporateAccount public void deleteCorporateAccount(String bankAccountId) throws java.rmi.RemoteException { try { CorporateAccount corporateAccountToDelete = getCorporateAccount(bankAccountId); corporateAccountToDelete.remove(); } catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.deleteCorporateAccount(String bankAccountId)", e); } } u deleteCustomer public void deleteCustomer(String customerId) throws java.rmi.RemoteException { try { Customer customerToDelete = getCustomer(customerId); customerToDelete.remove(); } catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.deleteCustomer(String customerId)", e); } } u deleteSavingsAccount public void deleteSavingsAccount(String bankAccountId) throws java.rmi.RemoteException { try { SavingsAccount savingsAccountToDelete = getSavingsAccount(bankAccountId); savingsAccountToDelete.remove();

Bank Implementation AdminSB

337

} catch(Exception e) { throw wrapperNonRemoteException("AdminSBBean.deleteSavingsAccount(String bankAccountId)", e); } }

Modify the Generated Methods


u getBankHome private BankHome getBankHome() throws RemoteException { if (bankHome == null) buildBankHome(); return bankHome; } u getCheckingAccountHome private CheckingAccountHome getCheckingAccountHome() throws RemoteException { if (checkingAccountHome == null) buildCheckingAccountHome(); return checkingAccountHome; } u getCorporateAccountHome private CorporateAccountHome getCorporateAccountHome() throws RemoteException { if (corporateAccountHome == null) buildCorporateAccountHome(); return corporateAccountHome; } u getCustomerHome private CustomerHome getCustomerHome() throws RemoteException { if (customerHome == null) buildCustomerHome(); return customerHome; } u getSavingsAccountHome private SavingsAccountHome getSavingsAccountHome() throws RemoteException { if (savingsAccountHome == null) buildSavingsAccountHome(); return savingsAccountHome; }

338

Developing Enterprise JavaBeans with VisualAge for Java

Add Methods to the Remote Interface


Select the following methods and add them to the bean remote interface. For directions on how to add a method to the remote interface, see , Adding Methods to the Remote Interface on page 46.
u createBank u createCheckingAccount u createCorporateAccount u createCustomer u createSavingsAccount u deleteBank u deleteCheckingAccount u deleteCorporateAccount u deleteCustomer u deleteSavingsAccount

The AdminSB is almost ready for testing the bank administration.

Generate Deployed Code


You still need to generate the deployed code. The next step is to run and test the application. You can use the test client to verify the behavior of the AdminSB (See Running the Generated Test Client on page 64.) The very last step will be to package the application and deploy it on any EJB server. If we make the assumption that the administration client application is used in the intranet, then it could be developed as an EJB client application using JNDI and RMI or a pure CORBA application. The larger network bandwidth should allow the development of a GUI highly interactive based on swing classes for example.

Bank Implementation AdminSB

339

340

Developing Enterprise JavaBeans with VisualAge for Java

Part 3

APPENDIXES

Copyright IBM Corp. 1999

341

342

Developing Enterprise JavaBeans with VisualAge for Java

ITSOBANK database

Copyright IBM Corp. 1999

343

344

Developing Enterprise JavaBeans with VisualAge for Java

A Hints and Tips


A.1 Importing EJBs from a Jar File
Once you have added one or more EJB groups to the EJBs page, you can add EJBs to the EJB groups by: Importing EJBs from EJB jar files Creating new EJBs Retrieving existing EJBs from the repository This topic discusses how to add EJBs by importing EJBs from a jar file. Information about importing EJBs into a repository is found in the topic "Moving or Copying EJBs Between Repositories". Note that if an EJB you plan to import already exists in the EJBs page, it will not overwrite the existing EJB. Instead, you will receive an error message indicating that the EJB already exists. To import EJBs from a jar file:

Copyright IBM Corp. 1999

345

1. In the EJBs pane of the EJBs page, select the EJB group that you want to contain the imported EJBs. 2. Click mouse button 2, then select Import EJBs from the pop-up menu. The Import from an EJB Jar File SmartGuide appears.

Figure 150. Import from an EJB Jar File window

3. Beside the Filename field, type the name of the jar file you want to import. Alternatively, click the Browse button. A dialog appears. In the dialog, navigate to the jar file, select it, and click OK. The SmartGuide marks for importation all of the types and beans found in the jar file. In the CDROM \Part1Samples\SessionBean we provide .jar file called CreateCustomerInfo.jar.This is an EJB jar file so it does not contain EJS jar file. Select it to try to import a EJB jar file.

346

Developing Enterprise JavaBeans with VisualAge for Java

Figure 151. Import from CreateCustomerInfo EJB Jar File

4. To select individual file types to import, click one or more of the following check boxes: beans: Import all the beans in the jar file. .class Import all the bytecode files in the jar file. .java Import all the source code files. resource Import all the non-.java and non-.class files Details By default, all the selected file types in the jar file are imported. Click the Details button next to a file type to see a list of the files in the jar file, and to specify individual files to import.

Hints and Tips

347

5. If needed specify additonal options using the Options check boxes as follows: Create new/scratch editions of versioned projects/packages If you are importing into a versioned EJB group, and you want to create a new or scratch edition of the versioned EJB group, click this check box.If you havent done a version of our ITSO BANK project you will not need this option. Overwrite existing resource files without warning If you do not want to be warned about overwriting existing resource files in the EJB group into which you are importing, click this check box. Version imported classes and new editions of packages/projects If you want to automatically version imported classes and the projects and packages they change, click this check box. Also, specify either automatic naming for the new version or a name of your own choosing by selecting either the Name automatically (recommended) radio button or the Version name radio button . 6. Click Finish. At this point in your ejb workspace shold look like this:

348

Developing Enterprise JavaBeans with VisualAge for Java

Figure 152. EJB Workspace after Importing and EJB .jar

Since we have imported and EJB jar file in order to test it you have to generata the deployed code first.To do this seeGenerate deployment code inside VisualAge for Java on page 55

A.2 Moving or Copying EJBs Between Repositories


To move or copy EJBs from one repository to another, do the following: 1. Go to the Projects page in the Workbench. 2. Select the project that contains the packages associated with your EJB group or EJB. These packages are the: Reserved package Package containing the EJB classes, interfaces, schemas, and maps Note that if these packages are spread across more than one project, you can expand these projects and do a multiple selection of the packages. However, we recommend that these associated packages be kept in a single project.

Hints and Tips

349

7. Version the project and export it as a .dat file into the target repository. (To open the export dialog, click on File - Export in the Packages page.) Note: If the target repository is on a different machine, once you export the project to the .dat file, move the .dat file to the other machine. Then, import the .dat file into the repository where you want to locate the project. (To open the import dialog, click on File - Import in the Packages page.)

A.3 Updating WebSphere Class Path

Figure 153. WebSphere Application Server Java Engine Setup

In the WebSphere Application server administration left pane choose Setup-Java Engine.Select the Path tab and add the C:\customerObject.jar in the Application Server Classpath field.

350

Developing Enterprise JavaBeans with VisualAge for Java

For this changes to make effect you need to stop and start WebSphere Advanced Edition 2.0

A.4 Starting and Stopping WebSphere Advanced Edition 2.0


To stop WebSphere: Shut down the Web server(from Start- Settings- Control PanelServices and select Lotus Domino Go Webserver click the Stop button.) Shut down the WebSphere ServletService to stop Application Server. (Select the WebSphere Servlet Service from StartSettings- Control Panel- Services and push the Stop button.) To start WebSphere: The server starts automatically when you start your Web server(from Start- Settings- Control Panel- Services and select Lotus Domino Go Webserver click the Start button.)

Hints and Tips

351

352

Developing Enterprise JavaBeans with VisualAge for Java

B Transaction Samples Appendix


B.1 Installing and running the transaction samples
B.1.1 Creating the DB2 database
1. You need to copy the following file from the cdrom to your SQLLIB\BIN (the directory where resides the DB2 executable files) directory: TRX.DDL These files comes the sample code provided on the CD-ROM. 2. Click on Start - Programs - DB2 - Command Window to start the DB2 command interpreter. 3. Type:
db2 -f TRX.DDL

then hit Enter. This creates the SampleDB database. 4. Type:


exit

Copyright IBM Corp. 1999

353

then hit Enter to close the DB2 command interpreter.

B.1.2 Importing the transaction.dat repository


1. In the Projects page of VisualAge for Java click the mouse button 2. Select Import.... 2. VisualAge for Java displays the Import SmartGuide. Select Repository as the import source. Click on the Next > button. 3. Select Local repository, then click on the Browse button. Select the your CD-Rom drive. From this drive go to the Part1Samples\transaction directory. Select the transaction.dat file then click on the Open button. 4. Select the Projects radio button, from the What do you want to import ?. 5. Click on the Details button. Choose the TransactionSamples project and click OK. 6. Click on the Finish button from the Import SmartGuide. VisualAge for Java imports all the classes.

B.1.3 Adding the TransactionSamples project to the workspace


1. In the Projects page of VisualAge for Java click the mouse button 2. Select Add - Project.... 2. VisualAge for Java displays the Add Project SmartGuide. Click on Add projects from the repository radio button. 3. Select the TransactionSamples project. Click on the Finish button. 4. The TransactionSamples project now appears in the Projects page of your workspace. 5. Click on the EJBs page. You should see the ITSOEJBSamples EJB Group with 3 EJBs in it as in Figure 154

354

Developing Enterprise JavaBeans with VisualAge for Java

Figure 154. ITSOEJBSamples EJB Group

B.1.4 Generating the deployed code and running the samples


1. Click on the EJBs page. You should see the ITSOEJBSamples EJB Group with 3 EJBs in it as in Figure 154. 1. Select the ITSOEJBSamples EJB Group from the EJBs list. 2. Click on the mouse button 2, select Generate - Deployed code from the popup menu. Wait until the code generation is completed. 3. Select the ITSOEJBSamples EJB Group from the EJBs list. 4. Select EJBs - Add To - Server Configuration from the menu. 5. Start the Location Service Daemon. 6. Start the Persistent Name Server. 7. Select the EJB Server (server1) from the Servers list. Click on the mouse button 2 and select Start server. 8. Switch to the VisualAge for Java Console to check if your server is started. 9. Switch back to your workspace. Click on the Projects page. Expand the com.alain.cmps package. Select the SimpleClient class and click on the Run icon from the toolbar. 10.Wait for a moment and VisualAge for Javas console will appear and ask you for some input. 11. The output done from the SimpleClient and the Beans can be seen on the Console.

Transaction Samples Appendix

355

B.2 Output Samples


TransactionTest Output: -------Starting Client-demarcated commited transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: Retrieving User Transaction... TransactionTest Output: Transaction Status after mySessionCtx.getUserTransaction() is: 6 TransactionTest Output: ******************* TransactionTest: afterBegin() **************88 TransactionTest Output: Transaction Status after myTransaction.begin() is: 0 TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: 1 TransactionTest Output: Object 1 found. CMPSample1 Output: Enter key value for CMP2 Entity Bean: CMPSample1 Output: Enter state value: CMPSample1 Output: -------Retrieving initial context... CMPSample1 Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 CMPSample1 Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory CMPSample1 Output: -------Invoke: javax.naming.InitialContext(properties) CMPSample1 Output: CMPSample2Bean CMPSample1 Output: Retrieving the home interface... CMPSample1 Output: Searching for existing object with this key: 1 CMPSample1 Output: Object 1 found. CMPSample1 Output: State updated. TransactionTest Output: State updated. TransactionTest Output: ********************* TransactionTest: beforeCompletion() ************** CMPSample1 Output: ********************* CMPSample1: beforeCompletion() ************** CMPSample2 Output: ********************* CMPSample2: beforeCompletion() ************** TransactionTest Output: ************************** TransactionTest: afterCompletion() ************ CMPSample1 Output: ************************** CMPSample1: afterCompletion() ************ CMPSample2 Output: ************************** CMPSample2: afterCompletion() ************ TransactionTest Output: Transaction Status after myTransaction.commit() is :6

Scenario 1 - myTransactionTest.test1() sample output

356

Developing Enterprise JavaBeans with VisualAge for Java

TransactionTest Output: -------Starting Client-demarcated rollbacked transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: ******************* TransactionTest: afterBegin() **************88 TransactionTest Output: Transaction Status after myTransaction.begin() is: 0 TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: 1 TransactionTest Output: Object 1 found. CMPSample1 Output: Enter key value for CMP2 Entity Bean: CMPSample1 Output: Enter state value: CMPSample1 Output: -------Retrieving initial context... CMPSample1 Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 CMPSample1 Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory CMPSample1 Output: -------Invoke: javax.naming.InitialContext(properties) CMPSample1 Output: CMPSample2Bean CMPSample1 Output: Retrieving the home interface... CMPSample1 Output: Searching for existing object with this key: 1 CMPSample1 Output: Object 1 found. CMPSample1 Output: State updated. TransactionTest Output: State updated. TransactionTest Output: ************************** TransactionTest: afterCompletion() ************ CMPSample1 Output: ************************** CMPSample1: afterCompletion() ************ CMPSample2 Output: ************************** CMPSample2: afterCompletion() ************ TransactionTest Output: Transaction Status after myTransaction.rollback() is :6

Scenario 1 - myTransactionTest.test2() sample output

Transaction Samples Appendix

357

TransactionTest Output: -------Starting Container-demarcated transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: 13 TransactionTest Output: Object 13 found. CMPSample1 Output: ******************* CMPSample1: afterBegin() **************88 CMPSample1 Output: Enter key value for CMP2 Entity Bean: CMPSample1 Output: Enter state value: CMPSample1 Output: -------Retrieving initial context... CMPSample1 Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 CMPSample1 Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory CMPSample1 Output: -------Invoke: javax.naming.InitialContext(properties) CMPSample1 Output: CMPSample2Bean CMPSample1 Output: Retrieving the home interface... CMPSample1 Output: Searching for existing object with this key: 13 CMPSample1 Output: Object 13 found. CMPSample1 Output: State updated. CMPSample1 Output: ********************* CMPSample1: beforeCompletion() ************** CMPSample2 Output: ********************* CMPSample2: beforeCompletion() ************** CMPSample1 Output: ************************** CMPSample1: afterCompletion() ************ CMPSample2 Output: ************************** CMPSample2: afterCompletion() ************ TransactionTest Output: State updated.

Scenario 1 - myTransactionTest.test3() sample output

358

Developing Enterprise JavaBeans with VisualAge for Java

TransactionTest Output: -------Starting Client-demarcated commited transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: Retrieving User Transaction... TransactionTest Output: Transaction Status after mySessionCtx.getUserTransaction() is: 6 TransactionTest Output: ******************* TransactionTest: afterBegin() **************88 TransactionTest Output: Transaction Status after myTransaction.begin() is: 0 TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: 1 TransactionTest Output: Object 1 found. CMPSample1 Output: ******************* CMPSample1: afterBegin() **************88 CMPSample1 Output: Enter key value for CMP2 Entity Bean: CMPSample1 Output: Enter state value: CMPSample1 Output: -------Retrieving initial context... CMPSample1 Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 CMPSample1 Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory CMPSample1 Output: -------Invoke: javax.naming.InitialContext(properties) CMPSample1 Output: CMPSample2Bean CMPSample1 Output: Retrieving the home interface... CMPSample1 Output: Searching for existing object with this key: 1 CMPSample1 Output: Object 1 found. CMPSample2 Output: ******************* CMPSample2: afterBegin() **************88 CMPSample1 Output: State updated. TransactionTest Output: State updated. TransactionTest Output: ********************* TransactionTest: beforeCompletion() ************** CMPSample1 Output: ********************* CMPSample1: beforeCompletion() ************** CMPSample2 Output: ********************* CMPSample2: beforeCompletion() ************** TransactionTest Output: ************************** TransactionTest: afterCompletion() ************ CMPSample1 Output: ************************** CMPSample1: afterCompletion() ************ CMPSample2 Output: ************************** CMPSample2: afterCompletion() ************ TransactionTest Output: Transaction Status after myTransaction.commit() is :6

Scenario 2- myTransactionTest.test1() sample output

Transaction Samples Appendix

359

TransactionTest Output: -------Starting Client-demarcated rollbacked transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: ******************* TransactionTest: afterBegin() **************88 TransactionTest Output: Transaction Status after myTransaction.begin() is: 0 TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: toe TransactionTest Output: Object not found. Creating a new instance... TransactionTest Output: New Object instance created! CMPSample1 Output: ******************* CMPSample1: afterBegin() **************88 CMPSample1 Output: Enter key value for CMP2 Entity Bean: CMPSample1 Output: Enter state value: CMPSample1 Output: -------Retrieving initial context... CMPSample1 Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 CMPSample1 Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory CMPSample1 Output: -------Invoke: javax.naming.InitialContext(properties) CMPSample1 Output: CMPSample2Bean CMPSample1 Output: Retrieving the home interface... CMPSample1 Output: Searching for existing object with this key: toe CMPSample1 Output: Object not found. Creating a new instance... CMPSample1 Output: New Object instance created! CMPSample2 Output: ******************* CMPSample2: afterBegin() **************88 CMPSample1 Output: State updated. TransactionTest Output: State updated. TransactionTest Output: ************************** TransactionTest: afterCompletion() ************ CMPSample1 Output: ************************** CMPSample1: afterCompletion() ************ CMPSample2 Output: ************************** CMPSample2: afterCompletion() ************ TransactionTest Output: Transaction Status after myTransaction.rollback() is :6

Scenario 2- myTransactionTest.test2() sample output

360

Developing Enterprise JavaBeans with VisualAge for Java

TransactionTest Output: -------Starting Container-demarcated transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: 23 TransactionTest Output: Object 23 found. 109.054 00006c47 EJSRemote W Bean method raised execption: javax.jts.TransactionRequiredException java.lang.Throwable() java.lang.Exception() java.io.IOException() java.rmi.RemoteException() javax.jts.TransactionRequiredException() boolean com.transarc.jmon.container.tran.TransactionControlImpl$Mandatory.tranBegin(com.ibm.ejs.contain boolean com.transarc.jmon.container.tran.TransactionControlImpl.tranBeginControl(com.ibm.ejs.container.E boolean com.transarc.jmon.container.tran.TransactionControlImpl.tranBeginControl(com.ibm.ejs.container.E boolean com.ibm.ejs.container.EJSContainer.preInvoke(com.ibm.ejs.container.EJSRemote, int) boolean com.ibm.ejs.container.EJSEntityRemote.preInvoke(int) void com.alain.cmps.EJSRemoteCMPSample1.setState(java.lang.String) void com.alain.cmps._CMPSample1Skeleton.setState(java.lang.String) java.lang.Object com.alain.cmps._CMPSample1Skeleton._dispatch(com.alain.cmps.CMPSample1, int, long java.lang.Object [], org.omg.CORBA.Context) java.lang.Object com.alain.cmps._CMPSample1Skeleton._dispatch(int, int, long [], java.lang.Object [], org.omg.CORBA.Context) void com.ibm.CORBA.iiop.GenericServerSC.dispatch(com.ibm.CORBA.iiop.IIOPInputStream, com.ibm.CORBA.iiop.IIOPOutputStream) void com.ibm.CORBA.iiop.ORB.dispatch(com.ibm.CORBA.iiop.IIOPInputStream, com.ibm.CORBA.iiop.IIOPOutputStream) void com.ibm.CORBA.iiop.WorkerThread.run()

TransactionTest Output: The setState() method needs a transaction to be processed.

Scenario 2- myTransactionTest.test2() sample output

Transaction Samples Appendix

361

TransactionTest Output: -------Starting Client-demarcated commited transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: Retrieving User Transaction... TransactionTest Output: Transaction Status after mySessionCtx.getUserTransaction() is: 6 TransactionTest Output: ******************* TransactionTest: afterBegin() **************88 TransactionTest Output: Transaction Status after myTransaction.begin() is: 0 TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: 1 TransactionTest Output: Object not found. Creating a new instance... TransactionTest Output: New Object instance created! CMPSample1 Output: Enter key value for CMP2 Entity Bean: CMPSample1 Output: Enter state value: CMPSample1 Output: -------Retrieving initial context... CMPSample1 Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 CMPSample1 Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory CMPSample1 Output: -------Invoke: javax.naming.InitialContext(properties) CMPSample1 Output: CMPSample2Bean CMPSample1 Output: Retrieving the home interface... CMPSample1 Output: Searching for existing object with this key: 1 CMPSample1 Output: New Object instance created! CMPSample1 Output: State updated. TransactionTest Output: State updated. TransactionTest Output: ********************* TransactionTest: beforeCompletion() ************** TransactionTest Output: ************************** TransactionTest: afterCompletion() ************ TransactionTest Output: Transaction Status after myTransaction.commit() is :6 TransactionTest Output: -------Starting Client-demarcated rollbacked transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: ******************* TransactionTest: afterBegin() **************88 TransactionTest Output: Transaction Status after myTransaction.begin() is: 0 TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: 9 066.434 00000992 EJSEntityHome < findOrActivateFromKey: object not found com.ibm.ejs.container.ContainerObjectNotFoundException java.lang.Throwable() java.lang.Exception() java.io.IOException() java.rmi.RemoteException() com.ibm.ejs.EJSException() com.ibm.ejs.container.ContainerException() com.ibm.ejs.container.ContainerObjectNotFoundException()

Scenario 3 sample output

362

Developing Enterprise JavaBeans with VisualAge for Java

TransactionTest Output: -------Starting Client-demarcated commited transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: Retrieving User Transaction... TransactionTest Output: Transaction Status after mySessionCtx.getUserTransaction() is: 6 TransactionTest Output: ******************* TransactionTest: afterBegin() **************88 TransactionTest Output: Transaction Status after myTransaction.begin() is: 0 TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: q TransactionTest Output: Object not found. Creating a new instance... TransactionTest Output: New Object instance created! CMPSample1 Output: ******************* CMPSample1: afterBegin() **************88 044.000 000058bd Transactional > lock com.transarc.encina.jts.CoordinatorImpl@26444#tid=3 IWRITE 044.051 000058bd Mutex E Mutex aquired forThread[Thread-10,5,main] 044.054 000058bd Transactional > conflict com.transarc.encina.jts.CoordinatorImpl@26444#tid=3 IWRITE 044.075 000058bd Transactional < conflict, true 044.077 000058bd Transactional > addWaiter, com.transarc.jmon.lock.Locker@7315 044.078 000058bd Transactional > isHolder 044.081 000058bd Transactional < isHolder, false, com.transarc.encina.jts.CoordinatorImpl@26444#tid=3 044.083 000058bd Transactional < addWaiter 044.084 000058bd Mutex E Mutex released 044.085 000058bd Transactional E Waiting for lock

Scenario 4 sample output

Transaction Samples Appendix

363

TransactionTest Output: -------Starting Client-demarcated commited transaction Scenario... TransactionTest Output: -------Retrieving initial context... TransactionTest Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 TransactionTest Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory TransactionTest Output: -------Invoke: javax.naming.InitialContext(properties) TransactionTest Output: Retrieving the home interface... TransactionTest Output: Retrieving User Transaction... TransactionTest Output: Transaction Status after mySessionCtx.getUserTransaction() is: 6 TransactionTest Output: ******************* TransactionTest: afterBegin() **************88 TransactionTest Output: Transaction Status after myTransaction.begin() is: 0 TransactionTest Output: CMPSample1 Object... TransactionTest Output: Enter key value: TransactionTest Output: Enter state value: TransactionTest Output: Searching for existing object with this key: qaz TransactionTest Output: Object not found. Creating a new instance... TransactionTest Output: New Object instance created! CMPSample1 Output: Enter key value for CMP2 Entity Bean: CMPSample1 Output: Enter state value: CMPSample1 Output: -------Retrieving initial context... CMPSample1 Output: -------Set properties to: javax.naming.Context.PROVIDER_URL, iiop://cobalt:900 CMPSample1 Output: -------Set properties to: com.ibm.jndi.CosNaming.CNInitialContextFactory CMPSample1 Output: -------Invoke: javax.naming.InitialContext(properties) CMPSample1 Output: CMPSample2Bean CMPSample1 Output: Retrieving the home interface... CMPSample1 Output: Searching for existing object with this key: qaz CMPSample1 Output: New Object instance created! CMPSample2 Output: ******************* CMPSample2: afterBegin() **************88 056.593 00002ccc Transactional > lock com.transarc.encina.jts.CoordinatorImpl@20391#tid=3 IWRITE 056.597 00002ccc Mutex E Mutex aquired forThread[Thread-14,5,main] 056.599 00002ccc Transactional > conflict com.transarc.encina.jts.CoordinatorImpl@20391#tid=3 IWRITE 056.724 00002ccc Transactional < conflict, true 056.727 00002ccc Transactional > addWaiter, com.transarc.jmon.lock.Locker@6c5f 056.729 00002ccc Transactional > isHolder 056.731 00002ccc Transactional < isHolder, false, com.transarc.encina.jts.CoordinatorImpl@20391#tid=3 056.733 00002ccc Transactional < addWaiter 056.735 00002ccc Mutex E Mutex released 056.748 00002ccc Transactional E Waiting for lock

Scenario 4 sample output

364

Developing Enterprise JavaBeans with VisualAge for Java

C ITSOBANK database
C.1 database Definition DDL
We use te command line processor commands and SQL statements to create the database and the information within it. Figure 155 and Figure 156 show the definitions of the tables. Figure 157 shows the foreign key relationships and the grant statements.

Copyright IBM Corp. 1999

365

echo --- create the ITSOBANK database --echo CREATE DATABASE ITSOBANK echo --- connect to ITSOBANK database --CONNECT TO ITSOBANK echo --- drop all tables --DROP TABLE ITSO.BANK DROP TABLE ITSO.CUSTOMER DROP TABLE ITSO.CARD DROP TABLE ITSO.POLICY DROP TABLE ITSO.ACCOUNT DROP TABLE ITSO.SAVINGS DROP TABLE ITSO.CHECKING DROP TABLE ITSO.PAYEE DROP TABLE ITSO.TRANSRECORD DROP TABLE ITSO.CARDACCOUNT DROP SYNONYM ITSO.TRANS echo --- creating tables --CREATE TABLE ITSO.BANK ( bankid CHAR( 4) NOT NULL, bankname CHAR(30) NOT NULL, PRIMARY KEY (BANKID) ) CREATE TABLE ITSO.CUSTOMER ( custid CHAR( 4) NOT NULL, title CHAR( 3) NOT NULL, fname CHAR(30) NOT NULL, lname CHAR(30) NOT NULL, userid CHAR( 8), password CHAR( 8), bankid CHAR( 4) NOT NULL, PRIMARY KEY (CUSTID) )

\ \ \ \

\ \ \ \ \ \ \ \ \

Figure 155. ITSOBANK Database Data Definition Language (Part1)

366

Developing Enterprise JavaBeans with VisualAge for Java

CREATE TABLE ITSO.ACCOUNT ( accid CHAR( 8) NOT NULL, bankid CHAR( 4), custid CHAR( 4) NOT NULL, acctype CHAR(10) NOT NULL, balance DEC(8,2) NOT NULL, PRIMARY KEY (ACCID) ) CREATE TABLE ITSO.SAVINGS ( accid CHAR(8) NOT NULL, minamt DECIMAL(8,2) NOT NULL, PRIMARY KEY (accid) ) CREATE TABLE ITSO.PAYEE ( accid CHAR(8) NOT NULL, title CHAR(20), PRIMARY KEY (accid) ) CREATE TABLE ITSO.CHECKING ( accid CHAR(8) NOT NULL, overdraf DECIMAL(8,2) NOT NULL, PRIMARY KEY (accid) ) CREATE TABLE ITSO.TRANSRECORD ( transid TIMESTAMP NOT NULL, accid CHAR( 8) NOT NULL, transtype CHAR( 1) NOT NULL, transamt DEC(8,2) NOT NULL, traccid CHAR( 8), PRIMARY KEY (TRANSID) )

\ \ \ \ \ \ \

\ \ \ \

\ \ \ \

\ \ \ \

\ \ \ \ \ \ \

Figure 156. ITSOBANK Database Data Definition Language (Part 2)

ITSOBANK database

367

CREATE SYNONYM ITSO.TRANS FOR ITSO.TRANSRECORD echo --- referential integrity --ALTER TABLE ITSO.TRANSRECORD \ ADD CONSTRAINT "AccountTransrecord" FOREIGN KEY (ACCID) \ REFERENCES ITSO.ACCOUNT ON DELETE RESTRICT ALTER TABLE ITSO.ACCOUNT \ ADD CONSTRAINT "CustomerAccount" FOREIGN KEY (CUSTID) \ REFERENCES ITSO.CUSTOMER ON DELETE RESTRICT ALTER TABLE ITSO.ACCOUNT \ ADD CONSTRAINT "BankAccount" FOREIGN KEY (BANKID) REFERENCES ITSO.BANK ALTER TABLE ITSO.CUSTOMER \ ADD CONSTRAINT "BankCustomer" FOREIGN KEY (BANKID) REFERENCES ITSO.BANK ON DELETE RESTRICT

echo --- execute GRANT statements --GRANT BINDADD ON DATABASE GRANT CONNECT ON DATABASE GRANT ALL ON ITSO.BANK GRANT ALL ON ITSO.CUSTOMER GRANT ALL ON ITSO.ACCOUNT GRANT ALL ON ITSO.SAVINGS GRANT ALL ON ITSO.CHECKING GRANT ALL ON ITSO.PAYEE GRANT ALL ON ITSO.TRANSRECORD GRANT ALL ON ITSO.TRANS echo --- connect reset --CONNECT RESET

TO PUBLIC TO PUBLIC TO PUBLIC TO PUBLIC TO PUBLIC TO PUBLIC TO PUBLIC TO PUBLIC TO PUBLIC TO PUBLIC

Figure 157. ITSOBANK Database Data Definition Language (Part 3)

368

Developing Enterprise JavaBeans with VisualAge for Java

Execute the following command from a DB2 command line processor:


db2 -f itsobank.ddl

You can either create the file itsobank.ddl from the above tables or get it from the CDROM or zip file that you can download from the ITSO web site in the subdirectory:
CdRom\Part2BankApplication

C.2 Sample Data of ITSOBANK Tables


The database tables are initiliazed with the data described in itsobank.sql described in the following Figure 158, Figure 159, Figure 160 and Figure 161.

connect to ITSOBANK echo --- insert into BANK table --INSERT INTO ITSO.BANK (bankid, bankname ) VALUES (ITSO,THE ITSO BANK) echo --- insert into CUSTOMER table --INSERT INTO ITSO.CUSTOMER (custid, title, fname, lname, userid, password, bankid) VALUES (101, Mr., John, Akerley, cust101, JA, ITSO), (102, Mr., Pat, McCarthy, cust102, PM, ITSO), (103, Mr., Markus, Muetschard, cust103, MM, ITSO), (104, Mr., Joaquin, Picon, cust104, JP, ITSO), (105, Ms., Unknown, Lady, null, null, ITSO), (106, Mr., Ueli, Wahli, cust106, UW, ITSO), (901, THE, XYZ, CORPORATION, null, null, ITSO) \ \ \ \ \ \ \ \ \ \

Figure 158. ITSOBANK Data (Part 1)

ITSOBANK database

369

echo --- insert into ACCOUNT table --INSERT INTO ITSO.ACCOUNT (accid, bankid, custid, acctype, balance) VALUES (101-1001, ITSO, 101, CHECKING, 80.00), (101-1002, ITSO, 101, SAVINGS, 375.26), (102-2001, ITSO, 102, SAVINGS, 9375.26), (102-2002, ITSO, 102, CHECKING, 75.50), (103-3001, ITSO, 103, SAVINGS, 100.00), (103-3002, ITSO, 103, CHECKING, 222.22), (104-4001, ITSO, 104, CHECKING, 362.00), (104-4002, ITSO, 104, CHECKING, 5.00), (105-5001, ITSO, 105, CHECKING, 0.00), (106-6001, ITSO, 106, CHECKING, 1000.00), (106-6002, ITSO, 106, SAVINGS, 2000.00), (106-6003, ITSO, 106, SAVINGS, 3000.00), (106-6004, ITSO, 106, CHECKING, 4000.00), (901-9001, ITSO, 901, PAYEE, 4000.00) \ \ \ \ \ \ \ \ \ \ \ \ \ \

echo --- insert into SAVINGS table --INSERT INTO ITSO.SAVINGS (accid, minamt) VALUES (101-1002, 100.00), (102-2001, 100.00), (103-3001, 100.00), (106-6002, 100.00), (106-6003, 100.00) \ \ \ \ \

Figure 159. ITSOBANK Data (Part 2)

370

Developing Enterprise JavaBeans with VisualAge for Java

echo --- insert into CHECKING table --INSERT INTO ITSO.CHECKING (accid, overdraf) VALUES (101-1001, 200.00), (102-2002, 200.00), (103-3002, 200.00), (104-4001, 200.00), (104-4002, 200.00), (105-5001, 200.00), (106-6001, 200.00), (106-6004, 200.00) echo --- insert into PAYEE table --INSERT INTO ITSO.PAYEE (accid, title ) VALUES (901-9001, XYZ VISA) \ \ \ \ \ \ \ \ \ \ \

Figure 160. ITSOBANK Data (Part 3)

ITSOBANK database

371

echo --- insert into TRANSRECORD table --INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt) VALUES (CURRENT TIMESTAMP, 101-1001, C, 80.00 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt) VALUES (CURRENT TIMESTAMP, 101-1002, C, 200.00 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt) VALUES (CURRENT TIMESTAMP, 102-2002, C, 75.50 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt) VALUES (CURRENT TIMESTAMP, 103-3001, C, 100.00 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt) VALUES (CURRENT TIMESTAMP, 104-4001, C, 200.00 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt) VALUES (CURRENT TIMESTAMP, 106-6001, D, 250.00 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt) VALUES (CURRENT TIMESTAMP, 106-6002, C, 400.00 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt) VALUES (CURRENT TIMESTAMP, 106-6003, C, 350.00 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt) VALUES (CURRENT TIMESTAMP, 106-6004, D, 100.00 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt, traccid) VALUES (CURRENT TIMESTAMP, 106-6001, T, 66.66, 106-6002 ) INSERT INTO ITSO.TRANSRECORD (transid, accid, transtype, transamt, traccid) VALUES (CURRENT TIMESTAMP, 106-6002, F, 66.66, 106-6001 ) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

echo --- connect reset --connect reset

Figure 161. ITSOBANK Data (Part 4)

372

Developing Enterprise JavaBeans with VisualAge for Java

D Samples and BANK Application


All the code developed for this book can be found in the accompanying CDROM or downloaded from: ftp://www.redbooks.ibm.com/redbooks/SG245429 The code is stored under the following directory structure:

Figure 162. SG24-5429 Directory Structure

Al the code is provided as VisualAge for Java repositories.

Copyright IBM Corp. 1999

373

We provide hereafter a complete list of packages, interfaces and classes created and generated by VisualAge for Java for the bank application:
u package ITSOBankEJBReserved

classes: AdminSB Bank BankAccount CheckingAccount CorporateAccount Customer SavingsAccount TransactionRecord UserSB
u package com.ibm.CORBA.java.Exception.itso.bank.ejb

BankTransactionExceptionValue
u package itso.bank.ejb

Interfaces: Bank BankAccount BankAccountBeanFinderHelper BankAccountHome BankBeanFinderHelper BankHome CheckingAccount CheckingAccountBeanFinderHelper CheckingAccountHome CorporateAccount CorporateAccountBeanFinderHelper CorporateAccountHome Customer CustomerBeanFinderHelper CustomerHome EJSFinderBankAccountBean EJSFinderBankBean EJSFinderCheckingAccountBean EJSFinderCorporateAccountBean EJSFinderCustomerBean EJSFinderSavingsAccountBean EJSFinderTransactionRecordBean SavingsAccount SavingsAccountBeanFinderHelper SavingsAccountHome

374

Developing Enterprise JavaBeans with VisualAge for Java

TransactionRecord TransactionRecordBeanFinderHelper TransactionRecordHome classes: BankAccountBean BankAccountHelper BankAccountHolder BankAccountHomeHelper BankAccountHomeHolder BankAccountKey BankAccountProxy BankAccountTestClient BankBean BankHelper BankHolder BankHomeHelper BankHomeHolder BankKey BankTestClient CheckingAccountBean CheckingAccountHelper CheckingAccountHolder CheckingAccountHomeHelper CheckingAccountHomeHolder CheckingAccountTestClient CorporateAccountBean CorporateAccountHelper CorporateAccountHolder CorporateAccountHomeHelper CorporateAccountHomeHolder CorporateAccountTestClient CustomerBean CustomerHelper CustomerHolder CustomerHomeHelper CustomerHomeHolder CustomerKey CustomerTestClient EJSBankAccountHome EJSBankHome EJSCheckingAccountHome EJSCorporateAccountHome EJSCustomerHome EJSJDBCFinderBankAccountBean EJSJDBCFinderBankBean

Samples and BANK Application

375

EJSJDBCFinderCheckingAccountBean EJSJDBCFinderCorporateAccountBean EJSJDBCFinderCustomerBean EJSJDBCFinderSavingsAccountBean EJSJDBCFinderTransactionRecordBean EJSJDBCPersisterBankAccountBean EJSJDBCPersisterBankBean EJSJDBCPersisterCheckingAccountBean EJSJDBCPersisterCorporateAccountBean EJSJDBCPersisterCustomerBean EJSJDBCPersisterSavingsAccountBean EJSJDBCPersisterTransactionRecordBean EJSRemoteBank EJSRemoteBankAccount EJSRemoteCheckingAccount EJSRemoteCorporateAccount EJSRemoteCustomer EJSRemoteSavingsAccount EJSRemoteTransactionRecord EJSSavingsAccountHome EJSTransactionRecordHome SavingsAccountBean SavingsAccountHelper SavingsAccountHolder SavingsAccountHomeHelper SavingsAccountHomeHolder SavingsAccountTestClient TransactionRecordBean TransactionRecordHelper TransactionRecordHolder TransactionRecordHomeHelper TransactionRecordHomeHolder TransactionRecordKey TransactionRecordTestClient _BankAccountHomeSkeleton _BankAccountHomeStub _BankAccountSkeleton _BankAccountStub _BankHomeSkeleton _BankHomeStub _BankSkeleton _BankStub _CheckingAccountHomeSkeleton _CheckingAccountHomeStub _CheckingAccountSkeleton

376

Developing Enterprise JavaBeans with VisualAge for Java

_CheckingAccountStub _CorporateAccountHomeSkeleton _CorporateAccountHomeStub _CorporateAccountSkeleton _CorporateAccountStub _CustomerHomeSkeleton _CustomerHomeStub _CustomerSkeleton _CustomerStub _SavingsAccountHomeSkeleton _SavingsAccountHomeStub _SavingsAccountSkeleton _SavingsAccountStub _TransactionRecordHomeSkeleton _TransactionRecordHomeStub _TransactionRecordSkeleton _TransactionRecordStub
upackage itso.bank.ejb.base

interfaces: ITSOEntity classes HomeFactory IBMJavaOrbRemoteObject ITSOEnterpriseBean ITSOEntityBean ITSOSessionBean


u package itso.bank.ejb.database

classes: BankMap BankSchema


u package itso.bank.ejb.inheritance.relation

classes: BankAccountManyLink BankAccountSingleLink TypeConverter


u package itso.bank.ejb.relation

classes: EJBObjectEnumeration EJBObjectEnumerationLink LinkBase ManyLink

Samples and BANK Application

377

SingleLink
u package itso.bank.ejb.sb.admin

interfaces: AdminSB AdminSBHome classes: AdminSBBean AdminSBHelper AdminSBHolder AdminSBHomeHelper AdminSBHomeHolder AdminSBTestClient EJSAdminSBHome EJSRemoteAdminSB _AdminSBHomeSkeleton _AdminSBHomeStub _AdminSBSkeleton _AdminSBStub
u package itso.bank.ejb.sb.user

interfaces: UserSB UserSBHome classes: EJSRemoteUserSB EJSUserSBHome UserSBBean UserSBHelper UserSBHolder UserSBHomeHelper UserSBHomeHolder UserSBTestClient _UserSBHomeSkeleton _UserSBHomeStub _UserSBSkeleton _UserSBStub
u package itso.bank.ejb.sb.user.UserSBPackage.java.lang

classes: StringX1dArrayHelper StringX1dArrayHolder StringX2dArrayHelper StringX2dArrayHolder

378

Developing Enterprise JavaBeans with VisualAge for Java

E Special Notices
This publication is intended to help application developers using VisualAge for Java to create distributed objects applications based on Enterprise JavaBeans.The information in this publication is not intended as the specification of any programming interfaces that are provided by VisualAge for Java enterprise Edition. See the PUBLICATIONS section of the IBM Programming Announcement for VisualAge for Java Enterprise Edition for more information about what publications are considered to be product documentation. References in this publication to IBM products, programs or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only IBMs product, program, or service may be used. Any functionally equivalent program that does not infringe any of IBMs intellectual property rights may be used instead of the IBM product, program or service. Information in this book was developed in conjunction with use of the equipment specified, and is limited in application to those specific hardware and software products and levels. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you

Copyright IBM Corp. 1999

379

any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing, IBM Corporation, 500 Columbus Avenue, Thornwood, NY 10594 USA. Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact IBM Corporation, Dept. 600A, Mail Drop 1329, Somers, NY 10589 USA. Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee. The information contained in this document has not been submitted to any formal IBM test and is distributed AS IS. The use of this information or the implementation of any of these techniques is a customer responsibility and depends on the customers ability to evaluate and integrate them into the customers operational environment. While each item may have been reviewed by IBM for accuracy in a specific situation, there is no guarantee that the same or similar results will be obtained elsewhere. Customers attempting to adapt these techniques to their own environments do so at their own risk. Any pointers in this publication to external Web sites are provided for convenience only and do not in any manner serve as an endorsement of these Web sites. The following terms are trademarks of the International Business Machines Corporation in the United States and/or other countries:
IBM DB2 S/390 ThinkPad MVS OS/390 VisualAge

The following terms are trademarks of other companies: C-bus is a trademark of Corollary, Inc. in the United States and/or other countries. Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and/or other countries. Microsoft, Windows, Windows NT, and the Windows logo are trademarks of

380

Developing Enterprise JavaBeans with VisualAge for Java

Microsoft Corporation in the United States and/or other countries. PC Direct is a trademark of Ziff Communications Company in the United States and/or other countries and is used by IBM Corporation under license. ActionMedia, LANDesk, MMX, Pentium and ProShare are trademarks of Intel Corporation in the United States and/or other countries. (For a complete list of Intel trademarks see www.intel.com/dradmarx.htm) UNIX is a registered trademark in the United States and/or other countries licensed exclusively through X/Open Company Limited. Other company, product, and service names may be trademarks or service marks of others.

Special Notices

381

382

Developing Enterprise JavaBeans with VisualAge for Java

F Related Publications
The publications listed in this section are considered particularly suitable for a more detailed discussion of the topics covered in this redbook.

F.1 International Technical Support Organization Publications


For information on ordering these ITSO publications see How to Get ITSO Redbooks on page 385.
u IBM Component Broker Connector Overview, SG24-2022 u IBM CBConnector Cookbook Collection: First Steps, SG24-2033 u IBM

CBConnector Cookbook Implementation, SG24-5119

Collection:

CBConnector

Bank

u Application Development with VisualAge for Java Enterprise, SG24-5081 u VisualAge for Java Enterprise Version 2 Team Support, SG24-5245 u Programming with VisualAge for Java, published by Prentice Hall,

ISBN 0-13-911371-1, 1998

Copyright IBM Corp. 1999

383

u Unlimited Enterprise Access with Java and VisualAge Generator,

SG24-5246
u Factoring JavaBeans in the Enterprise, SG24-5051 u From Client/Server to Network Computing, A Migration to Java,

SG24-2247
u JavaBeans by Example: Cooking with Beans in the Enterprise,

SG24-2035
u VisualAge for Java Enterprise Version 2

DataBeans - Servlets - CICS Connector, SG24-5265

F.2 Redbooks on CD-ROMs


Redbooks are also available on CD-ROMs. Order a subscription and receive updates 2-4 times a year at significant savings.
CD-ROM Title System/390 Redbooks Collection Networking and Systems Management Redbooks Collection Transaction Processing and Data Management Redbook Lotus Redbooks Collection Tivoli Redbooks Collection AS/400 Redbooks Collection RS/6000 Redbooks Collection (HTML, BkMgr) RS/6000 Redbooks Collection (PostScript) RS/6000 Redbooks Collection (PDF Format) Application Development Redbooks Collection Subscription Number SBOF-7201 SBOF-7370 SBOF-7240 SBOF-6899 SBOF-6898 SBOF-7270 SBOF-7230 SBOF-7205 SBOF-8700 SBOF-7290 Collection Kit Number SK2T-2177 SK2T-6022 SK2T-8038 SK2T-8039 SK2T-8044 SK2T-2849 SK2T-8040 SK2T-8041 SK2T-8043 SK2T-8037

F.3 Other Publications


These publications are also relevant as further information sources:
u Design Patterns: Elements of Reusable Object Oriented Software

(Addison-Wesley Professional Computing Series)

384

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429ord.fm

How to Get ITSO Redbooks


This section explains how both customers and IBM employees can find out about ITSO redbooks, CD-ROMs, workshops, and residencies. A form for ordering books and CD-ROMs is also provided. This information was current at the time of publication, but is continually subject to change. The latest information may be found at http://www.redbooks.ibm.com/.

How IBM Employees Can Get ITSO Redbooks


Employees may request ITSO deliverables (redbooks, BookManager BOOKs, and CD-ROMs) and information about redbooks, workshops, and residencies in the following ways: Redbooks Web Site on the World Wide Web
http://w3.itso.ibm.com/

PUBORDER to order hardcopies in the United States Tools Disks To get LIST3820s of redbooks, type one of the following commands:
TOOLCAT REDPRINT TOOLS SENDTO EHONE4 TOOLS2 REDPRINT GET SG24xxxx PACKAGE TOOLS SENDTO CANVM2 TOOLS REDPRINT GET SG24xxxx PACKAGE (Canadian users only)

To get BookManager BOOKs of redbooks, type the following command:


TOOLCAT REDBOOKS

To get lists of redbooks, type the following command:


TOOLS SENDTO USDIST MKTTOOLS MKTTOOLS GET ITSOCAT TXT

To register for information on workshops, residencies, and redbooks, type the following command:
TOOLS SENDTO WTSCPOK TOOLS ZDISK GET ITSOREGI 1998

REDBOOKS Category on INEWS Online send orders to: USIB6FPL at IBMMAIL or DKIBMBSH at IBMMAIL Redpieces For information so current it is still in the process of being written, look at "Redpieces" on the Redbooks Web Site (http://www.redbooks.ibm.com/redpieces.html). Redpieces are redbooks in progress; not all redbooks become redpieces, and sometimes just a few chapters will be published this way. The intent is to get the information out much quicker than the formal publishing process allows.

Copyright IBM Corp. 1999

385

5429ord.fm

Draft Document for Review April 14, 1999 3:55 pm

How Customers Can Get ITSO Redbooks


Customers may request ITSO deliverables (redbooks, BookManager BOOKs, and CD-ROMs) and information about redbooks, workshops, and residencies in the following ways: Online Orders send orders to: In United States In Canada Outside North America Telephone Orders United States (toll free) Canada (toll free) Outside North America (+45) 4810-1320 - Danish (+45) 4810-1420 - Dutch (+45) 4810-1540 - English (+45) 4810-1670 - Finnish (+45) 4810-1220 - French Mail Orders send orders to: IBM Publications Publications Customer Support P.O. Box 29570 Raleigh, NC 27626-0570 USA Fax send orders to: United States (toll free) Canada Outside North America 1-800-445-9269 1-800-267-4455 (+45) 48 14 2207 IBM Publications 144-4th Avenue, S.W. Calgary, Alberta T2P 3N5 Canada IBM Direct Services Sortemosevej 21 DK-3450 Allerd Denmark 1-800-879-2755 1-800-IBM-4YOU (long distance charges apply) (+45) 4810-1020 - German (+45) 4810-1620 - Italian (+45) 4810-1270 - Norwegian (+45) 4810-1120 - Spanish (+45) 4810-1170 - Swedish IBMMAIL usib6fpl at ibmmail caibmbkz at ibmmail dkibmbsh at ibmmail Internet usib6fpl@ibmmail.com lmannix@vnet.ibm.com bookshop@dk.ibm.com

(long distance charge)

1-800-IBM-4FAX (United States) or (+1) 408 256 5422 (Outside USA) ask for: Index # 4421 Abstracts of new redbooks Index # 4422 IBM redbooks Index # 4420 Redbooks for last six months On the World Wide Web Redbooks Web Site IBM Direct Publications Catalog http://www.redbooks.ibm.com http://www.elink.ibmlink.ibm.com/pbl/pbl

386

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429ord.fm

Redpieces For information so current it is still in the process of being written, look at "Redpieces" on the Redbooks Web Site (http://www.redbooks.ibm.com/redpieces.html). Redpieces are redbooks in progress; not all redbooks become redpieces, and sometimes just a few chapters will be published this way. The intent is to get the information out much quicker than the formal publishing process allows.

387

5429ord.fm

Draft Document for Review April 14, 1999 3:55 pm

IBM Redbook Order Form


Please send me the following: Title Order Quantit

First name Company Address City Telephone number Invoice to customer number Credit card number

Last name

Postal code Telefax number

Country VAT number

Credit card expiration date

Card issued to

Signature

We accept American Express, Diners, Eurocard, Master Card, and Visa. Payment by credit card not available in all countries. Signature mandatory for credit card payment.

388

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429glos.fm

Glossary
This glossary defines terms and abbreviations that are used in this book. If you do not find the term you are looking for, refer to the IBM Dictionary of Computing, New York: McGraw-Hill, 1994. This glossary includes terms and definitions from the American National Standard Dictionary for Information Systems, ANSI X3.172-1990, copyright 1990 by the American National Standards Institute (ANSI). Copies may be purchased from the American National Standards Institute, 1430 Broadway, New York, New York 10018. can be remotely invoked, usually by some for of remote object method call. argument. A data element, or value, included as a bean in a method call. Arguments provide additional information that the called method can use to perform the requested operation. attribute. A specification of a property of a bean. For example, a customer bean could have a name attribute and an address attribute. An attribute can itself be a bean with its own behavior and attributes. In the Data Access Builder, the aspect of a schema mapping that represents a column in a database table.

A
abstract class. A class that provides common behavior across a set of subclasses but is not itself designed to have instances that work. An abstract class represents a concept; classes derived from it represent implementations of the concept. See also base class. access application. Generated by the Data Access Builder for each schema mapping, an executable GUI that provides access to the database using the other classes generated for the mapping. accessor methods. Methods that an object provides to define the interface to its instance variables. The accessor method to return the value of an instance variable is called a get method or getter method, and the accessor method to assign a value to an instance variable is called a set method or setter method. applet. A Java program designed to run within a Web browser. Contrast with application. application. In Java programming, a self-contained, stand-alone Java program that includes a main() method. Contrast with applet. application server. A server program that allows the installation of application specific software components, in a manner so that they

B
base class. A class from which other classes or beans are derived. A base class may itself be derived from another base class. See also abstract class. bean. A definition or instance of a JavaBeans component. See also JavaBeans. BeanInfo. (1) A companion class for a bean that defines a set of methods that can be accessed to retrieve information on the beans properties, events, and methods. (2) In the VisualAge for Java IDE, a page in the class browser that provides bean information. Bean-managed persistence. When an Enterprise JavaBeans performs its own long-term state management. beans palette. In the Visual Composition Editor, a two-column pane that contains prefabricated beans that you can select and manipulate to create programs. The left column contains categories of beans, and the right column contains beans for the selected category. The default set of beans generally represents JDK AWT components. You can add your own categories and beans to the beans palette. break point. A point in a computer program where the execution can be halted.

Copyright IBM Corp. 1999

389

5429glos.fm
browser. (1) In VisualAge for Java, a window that provides information on program elements. There are browsers for projects, packages, classes, methods, and interfaces. (2) An Internet-based tool that lets users browse Web sites.

Draft Document for Review April 14, 1999 3:55 pm

another location and awaits a response. The requesting program is called a client, and the answering program is called a server. client-side server proxy. Generated by the RMI Access Builder, a local representative of a remote bean. This proxy provides access to the operations of the server bean, allowing a Java client to work with it as if it were the server bean. See also proxy bean and server-side server proxy. Class Browser. In the VisualAge for Java IDE, a tool used to browse the classes loaded in the workspace. collection. A set of features in which each feature is an object. commit. The operation that ends a unit of work and updates the database such that other processes can access any changes made. Common Object Request Broker Architecture (CORBA). A middleware specification which defines a software busthe Object Request Broker (ORB)that provides the infrastructure. communications area (COMMAREA). In a CICS transaction program, a group of records that describes both the format and volume of data used. component model. An architecture and an API that allows developers to define reusable segments of code that can be combined to create a program. VisualAge for Java uses the JavaBeans component model. composite bean. A bean that is composed of a bean and one or more subbeans. A composite bean can contain visual beans, nonvisual beans, or both. See also nonvisual bean, bean, and visual bean. concrete class. A subclass of an abstract class that is a specialization of the abstract class. connection. In the Visual Composition Editor, a visual link between two components that represents the relationship between the components. Each connection has a source, a target, and other properties. See also

C
C++ Access Builder. A VisualAge for Java Enterprise tool that generates beans to access C and C++ DLLs. category. In the Visual Composition Editor, a selectable grouping of beans represented by an icon in the left-most column. Selecting a category displays the beans belonging to that category in the next column. See also beans palette. CICS Access Builder. A VisualAge for Java Enterprise tool that generates beans to access CICS transactions through the CICS Gateway for Java and CICS Client. CICS Client. A server program that processes CICS ECI calls, forwarding transaction requests to a CICS program running on a host. CICS ECI. An API that provides C and C++ programs with procedural access to transactions. CICS Gateway for Java. A server program that processes Java ECI calls and forwards CICS ECI calls to the CICS Client. class. An aggregate that defines properties, operations, and behavior for all instances of that aggregate. class hierarchy. The relationships between classes that share a single inheritance. All Java classes inherit from the Object class. class library. A collection of classes. class method. See method. CLASSPATH. In your deployment environment, the environment variable that specifies the directories in which to look for class and resource files. client/server. The model of interaction in distributed data processing where a program at one location sends a request to a program at

390

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429glos.fm
DB2 for MVS/ESA. An IBM relational database management system for the MVS operating system. double-byte character set (DBCS). A set of characters in which each character is represented by 2 bytes. Languages such as Japanese, Chinese, and Korean, which contain more symbols than can be represented by 256 code points, require double-byte character sets. Compare with single-byte character set. Distributed Computing Environment (DCE). Adopted by the computer industry as a de facto standard for distributed computing. DCE allows computers from a variety of vendors to communicate transparently and share resources such as computing power, files, printers, and other objects in the network. Distributed Component Object Model (DCOM). A protocol that enables software components to communicate directly over a network in a reliable, secure, and efficient manner. Previously called "Network OLE," DCOM is designed for use across multiple network transports, including Internet protocols such as HTTP. DCOM is based on the Open Software Foundation's DCE-RPC specification and works with both Java applets and ActiveX components through its use of the Component Object Model (COM). dynamic link library (DLL). A file containing executable code and data bound to a program at run time rather than at link time. The C++ Access Builder generates beans and C++ wrappers that let your Java programs access C++ DLLs.

event-to-method connection, event-to-property connection, parameter connection, property-to-method connection, and property-to-property connection. console. In VisualAge for Java, the window that acts as the standard input (System.in) and standard output (System.out) device for programs running in the VisualAge for Java IDE. Container-managed persistence. When an Enterprise JavaBeans server manages a beans long term state. construction from parts. A software development technology in which applications are assembled from existing and reusable software components, known as parts. In VisualAge for Java, parts are called beans. constructor. A special class method that has the same name as the class and is used to construct and possibly initialize objects of its class type. container. A component that can hold other components. In Java, examples of containers include applets, frames, and dialogs. In the Visual Composition Editor, containers can be graphically represented and generated. current edition. The edition of a program element that is currently in the workspace. See also open edition. cursor. A database control structure used by the Data Access Builder to point to a specific row within some ordered set of rows and to retrieve rows from a set, possibly making updates or deletions.

D
data abstraction. A data type with a private representation and a public set of operations. The Java language uses the concept of classes to implement data abstraction. Data Access Builder. A VisualAge for Java Enterprise tool that generates beans to access and manipulate the content of JDBC/ODBC-compliant relational databases.

E
edition. A specific cut of a program element. VisualAge for Java supports multiple editions of program elements. See also current edition, open edition, and versioned edition. encapsulation. The hiding of a software objects internal representation. The object provides an interface that queries and manipulates the data without exposing its underlying structure.

391

5429glos.fm
enterprise access builders. In VisualAge for Java Enterprise, a set of code-generation tools. See also C++ Access Builder, CICS Access Builder, Data Access Builder, and RMI Access Builder. Enterprise JavaBeans. A server component developed by SUN Microsystems. event. An action by a user program, or a specification of a notification that may trigger specific behavior. In JDK 1.1, events notify the relevant listener classes to take appropriate actions. event-to-method connection. A connection from an event generated by a bean to a method of another bean. When the connected event occurs, the method is executed. See also connection. event-to-property connection. A connection that changes the value of a property when a certain event occurs. See also connection.

Draft Document for Review April 14, 1999 3:55 pm

G
garbage collection. A Smalltalk process for periodically identifying unreferenced objects and deallocating their memory. gateway. A host computer that connects networks that communicate in different languages. For example, a gateway connects a companys LAN to the Internet. graphical user interface (GUI). A type of interface that enables users to communicate with a program by manipulating graphical features, rather than by entering commands. Typically, a graphical user interface includes a combination of graphics, pointing devices, menu bars and other menus, overlapping windows, and icons.

H
hypertext. Text in a document that contains a hidden link to other text. You can click a mouse on a hypertext word and it will take you to the text designated in the link. Hypertext is used in Windows help programs and CD encyclopedias to jump to related references elsewhere within the same document. Hypertext can linkusing HTTP over the Webto any Web document in the world, with only a single mouse click. Hypertext Markup Language (HTML). The basic language that is used to build hypertext documents on the World Wide Web. It is used in basic, plain ASCII-text documents, but when those documents are interpreted (rendered) by a Web browser such as Netscape, the document can display formatted text, color, a variety of fonts, graphics images, special effects, hypertext jumps to other Internet locations, and information forms. Hypertext Transfer Protocol (HTTP). The protocol for moving hypertext files across the Internet. Requires an HTTP client program on one end, and an HTTP server program on the other end.

F
feature. (1) A major component of a software product that can be installed separately. (2) In VisualAge for Java, a method, field, or event that is available from a beans interface and to which other beans can connect. field. A data object in a class. For example, a customer class could have a name field and an address field. A field can itself be an object with its own behavior and fields. By default, a field, in contrast to a property, does not support event notification. free-form surface. The large open area of the Visual Composition Editor where you can work with visual and nonvisual beans. You add, remove, and connect beans on the free-form surface. framework. A set of cooperative classes with strong connections that provide a template for development.

392

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429glos.fm

I
inheritance. (1) A mechanism by which an object class can use the attributes, relationships, and methods defined in more abstract classes related to it (its base classes). (2) An object-oriented programming technique that allows you to use existing classes as bases for creating other classes. instance. Synonym for object, a particular instantiation of a data type. Integrated Development Environment (IDE). In VisualAge for Java, the set of windows that provide the user with access to development tools. The primary windows are Workbench, Log, Console, Debugger, and Repository Explorer. interchange file. A file that you can export from VisualAge for Java that contains information about selected projects or packages. This file can then be imported into any VisualAge for Java session. interface. A set of methods that can be accessed by any class in the class hierarchy. The Interface page in the Workbench lists all interfaces in the workspace. Internet. The vast collection of interconnected networks that use TCP/IP and evolved from the ARPANET of the late 1960s and early 1970s. intranet. A private network, inside a company or organization, that uses the same kinds of software that you would find on the public Internet. Many of the tools used on the Internet are being used in private networks; for example, many companies have Web servers that are available only to employees. Internet Protocol (IP). The rules that provide basic Internet functions. See Transmission Control Protocol/Internet Protocol. IP number. An Internet address that is a unique number consisting of four parts separated by dots, sometimes called a dotted quad (for example: 198.204.112.1). Every Internet computer has an IP number, and most computers also have one or more domain names that are plain language substitutes for the dotted quad.

J
Java. A programming language invented by Sun Microsystems that is specifically designed for writing programs that can be safely downloaded to your computer through the Internet and immediately run without fear of viruses or other harm to your computer or files. Using small Java programs (called applets), Web pages can include functions such as animation, calculators, and other fancy tricks. We can expect to see a huge variety of features added to the Web through Java, because you can write a Java program to do almost anything a regular computer program can do and then include that Java program in a Web page. Java archive (JAR). A platform-independent file format that groups many files into one. JAR files are used for compression, reduced download time, and security. Because the JAR format is written in Java, JAR files are fully extensible. JavaBeans. In JDK 1.1, the specification that defines the platform-neutral component model used to represent parts. Instances of JavaBeans (often called beans) may have methods, properties, and events. Java Database Connectivity (JDBC). In JDK 1.1, the specification that defines an API that enables programs to access databases that comply with this standard. Java Naming and Directory Interace. The Java standard API for accessing directory services, such as LDAP, COS Naming, and others. Java Native Interface (JNI). In JDK 1.1, the specification that defines a standard naming and calling convention so that the Java virtual machine can locate and invoke methods written in a language different from Java. See also native method. JTA. Java transaction API. JTS. The Java Transaction Service based on the CORBA Transaction Service which provides a way for middleware vendors to build interoperable transactional middleware.

393

5429glos.fm

Draft Document for Review April 14, 1999 3:55 pm

K
keyword. A predefined word, reserved for Java, that cannot be used as an identifier.

L
LDAP. Lightweight Directory Access Protocol for accessing X.500 directories. legacy code. Existing code that a user might have. Legacy applications often have character-based, nongraphical user interfaces. Usually they are written in a non-object-oriented language, such as C or COBOL. listener. In JDK 1.1, a class that receives and handles events. local area network (LAN). A computer network located on a users establishment within a limited geographical area. A LAN typically consists of one or more server machines providing services to a number of client workstations. log. In VisualAge for Java, the window that displays messages and warnings during development.

message. A request from one object that the receiving object implement a method. Because data is encapsulated and not directly accessible, a message is the only way to send data from one object to another. Each message specifies the name of the receiving object, the method to be implemented, and any arguments the method needs for implementation. Synonym for method call. model. A nonvisual bean that represents the state and behavior of an object, such as a customer or an account. Contrast with view.

N
native method. Method written in a language other than Java that can be called by a Java object through the JNI specification. named package. In the VisualAge for Java IDE, a package that has been explicitly named and created. nonvisual bean. In the Visual Composition Editor, a bean that has no visual representation at run time. A nonvisual bean typically represents some real-world object that exists in the business environment. Compare with model. Contrast with view and visual bean. notification framework. In JDK 1.1, a set of classes that implement the notifier/listener protocol. The notification framework is the base of the construction from beans technology (Visual Composition Editor).

M
mapping. See schema mapping. member. (1) A data object in a structure or a union. (2) In Java, classes and structures can also contain functions and types as members. method. A fragment of Java code within a class that can be invoked and passed a set of parameters to perform a specific task. method call. A communication from one object to another that requests the receiving object to execute a method. A method call consists of a method name that indicates the requested method and the arguments to be used in executing the method. The method call always returns some object to the requesting object as the result of performing the method. Synonym for message.

O
object. (1) A computer representation of something that a user can work with to perform a task. An object can appear as text or an icon. (2) A collection of data and methods that operate on that data, which together represent a logical entity in the system. In object-oriented programming, objects are grouped into classes that share common data definitions and methods. Each object in the class is said to be an instance of the class. (3) An instance of an object class consisting of attributes, a data structure, and operational methods. It can represent a

394

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429glos.fm
operation. A method or service that can be requested of an object. overloading. An object-oriented programming technique that allows redefinition of methods when the methods are used with class types.

person, place, thing, event, or concept. Each instance has the same properties, attributes, and methods as other instances of the object class, although it has unique values assigned to its attributes. object class. A template for defining the attributes and methods of an object. An object class can contain other object classes. An individual representation of an object class is called an object. object factory. A nonvisual bean capable of dynamically creating new instances of a specified bean. For example, during the execution of an application, an object factory can create instances of a new class to collect the data being generated. object-oriented programming (OOP). A programming approach based on the concepts of data abstraction and inheritance. Unlike procedural programming techniques, object-oriented programming concentrates on those data objects that constitute the problem and how they are manipulated, not on how something is accomplished. Object Request Broker (ORB). A CORBA term designating the means by which objects transparently make requests and receive responses from objects, whether they are local or remote. ODBC driver. A DLL that implements ODBC function calls and interacts with a data source. Open Database Connectivity (ODBC). A Microsoft developed C database API that allows access to database management systems calling callable SQL, which does not require the use of an SQL preprocessor. In addition, ODBC provides an architecture that allows users to add modules (database drivers) that link the application to their choice of database management systems at run time. Applications no longer need to be directly linked to the modules of all the database management systems that are supported. open edition. An edition of a program element that can still be modified; that is, the edition has not been versioned. An open edition may reside in the workspace as well as in the repository.

P
package. A program element that contains related classes and interfaces. palette. See beans palette. parameter connection. A connection that satisfies a parameter of an action or method by supplying either a propertys value or the return value of an action, method, or script. The parameter is always the source of the connection. See also connection. parent class. The class from which another bean or class inherits data, methods, or both. part. An existing, reusable software component. In VisualAge for Java, all parts created with the Visual Composition Editor conform to the JavaBeans component model and are referred to as beans. See also nonvisual bean and visual bean. Compare with Class Editor and Composition Editor. primitive bean. A basic building block of other beans. A primitive bean can be relatively complex in terms of the function it provides. private. In Java, an access modifier associated with a class member. It allows only the class itself to access the member. process. A collection of code, data, and other system resources, including at least one thread of execution, that performs a data processing task. program. In VisualAge for Java, a term that refers to both Java applets and applications. project. In VisualAge for Java, the topmost kind of program element. A project contains Java packages. promote features. Make features of a subbean available to be used for making connections. This applies to subbeans that are to be included in other beans, for example, a subbean consisting of

395

5429glos.fm
three push buttons on a panel. If this sample subbean is placed in a frame, the features of the push buttons would have to be promoted to make them available from within the frame. property. An initial setting or characteristic of a bean; for example, a name, font, text, or positional characteristic. property sheet. In the Visual Composition Editor, a set of name-value pairs that specify the initial appearance and other bean characteristics. A beans property sheet can be viewed from the Properties secondary window. property-to-method connection. A connection that calls a method whenever a propertys value changes. It is similar to an event-to-method connection because the propertys event ID is used to notify the method when the value of the property changes. See also connection. property-to-property connection. A connection from a property of one bean to a property of another bean. When one property is updated, the other property is updated automatically. See also connection. property-to-method connection. A connection from a property of a bean to a method. When the property undergoes a state change, the method is called. See also connection. protected. In Java, an access modifier associated with a class member. It allows the class itself, subclasses, and all classes in the same package to access the member. protocol. (1) The set of all messages to which an object will respond. (2) Specification of the structure and meaning (the semantics) of messages that are exchanged between a client and a server. (3) Computer rules that provide uniform specifications so that computer hardware and operating systems can communicate. It is similar to the way that mail, in countries around the world, is addressed in the same basic format so that postal workers know where to find the recipients address, the senders return address, and the postage stamp. Regardless of the underlying language, the basic protocols remain the same.

Draft Document for Review April 14, 1999 3:55 pm

prototype. A method declaration or definition that includes both the return type of the method and the types of its arguments. proxy bean. A group of client-side and server-side objects that represent a remote server bean. The top-level class that implements the proxy bean is the client-side server proxy. See also client-side server proxy and server-side server proxy.

R
Remote Method Invocation (RMI). In JDK 1.1, the API that enables you to write distributed Java programs, allowing methods of remote Java objects to be accessed from other Java virtual machines. remote object instance manager. Creates and manages instances of RMI server beans through their associated server-side server proxies. repository. In VisualAge for Java, the storage area, separate from the workspace, that contains all editions (both open and versioned) of all program elements that have ever been in the workspace, including the current editions that are in the workspace. You can add editions of program elements to the workspace from the repository. Repository Explorer. In VisualAge for Java, the window from which you can view and compare editions of program elements that are in the repository. resource file. A noncode file that can be referred to from your Java program in VisualAge for Java. Examples include graphics and audio files. RMI Access Builder. A VisualAge for Java Enterprise tool that generates proxy beans and associated classes and interfaces so you can distribute code for remote access, enabling Java-to-Java solutions. RMI compiler. The compiler that generates stub and skeleton files that facilitate RMI communication. This compiler can be automatically invoked by the RMI Access Builder or from the Tools menu item.

396

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429glos.fm
add multiple beans of the same class (for example, three push buttons) without going back and forth between the beans palette and the free-form surface. stored procedure. A procedure that is part of a relational database. The Data Access Builder can generate Java code that accesses stored procedures. superclass. See abstract class and base class.

RMI registry. A server program that allows remote clients to get a reference to a server bean. roll back. The process of restoring data changed by SQL statements to the state at its last commit point.

S
schema. In the Data Access Builder, the representation of the database that will be mapped. schema mapping. In the Data Access Builder, a set of definitions for all attributes matching all columns for your database table, view, or SQL statement. The mapping contains the information required by the Data Access Builder to generate Java classes. Scrapbook. In VisualAge for Java, the window from which you can write and test fragments of code, without having to define an encompassing class or method. server. A computer that provides services to multiple users or workstations in a network; for example, a file server, a print server, or a mail server. server bean. The bean that is distributed using RMI services and deployed on a server. server-side server proxy. Generated by the RMI Access Builder, a companion class to the client-side server proxy, facilitating client-side server proxy communication over RMI. See also client-side server proxy and proxy bean. service. A specific behavior that an object is responsible for exhibiting. single-byte character set. A set of characters in which each character is represented by a 1byte code. SmartGuide. In IBM software products, an interface that guides you through performing common tasks. SQL predicate. The conditional part of an SQL statement. sticky. In the Visual Composition Editor, the mode that enables an application developer to

T
Transmission Control Protocol/Internet Protocol (TCP/IP). The basic programming foundation that carries computer messages around the globe through the Internet. The suite of protocols that defines the Internet. Originally designed for the UNIX operating system, TCP/IP software is now available for every major kind of computer operating system. To be truly on the Internet, your computer must have TCP/IP software. tear-off property. A property that a developer has exposed to work with as though it were a stand-alone bean. thread. A unit of execution within a process. tool bar. The strip of icons along the top of the free-form surface. The tool bar contains tools to help an application developer construct composite beans. transaction. In a CICS program, an event that queries or modifies a database that resides on a CICS server. type. In VisualAge for Java, a generic term for a class or interface.

U
Unicode. A character coding system designed to support the interchange, processing, and display of the written texts of the diverse languages of the modern world. Unicode characters are normally encoded using 16-bit integral unsigned numbers.

397

5429glos.fm
uniform resource locator (URL). A standard identifier for a resource on the World Wide Web, used by Web browsers to initiate a connection. The URL includes the communications protocol to use, the name of the server, and path information identifying the objects to be retrieved on the server. A URL looks like this: http://www.matisse.net/seminars.html or telnet://well.sf.ca.us.br or news:new.newusers.question.br

Draft Document for Review April 14, 1999 3:55 pm

visual programming tool. A tool that provides a means for specifying programs graphically. Application programmers write applications by manipulating graphical representations of components. Visual Composition Editor. In VisualAge for Java, the tool where you can create graphical user interfaces from prefabricated beans and define relationships (connections) between both visual and nonvisual beans. The Visual Composition Editor is a page in the class browser.

user interface (UI). (1) The hardware, software, or both that enables a user to interact with a computer. (2) The visual presentation and its underlying software with which a user interacts.

W
Workbench. In VisualAge for Java, the main window from which you can manage the workspace, create and modify code, and open browsers and other tools. workspace. The work area that contains all the code you are currently working on (that is, current editions). The workspace also contains the standard Java class libraries and other class libraries. Your glossary term, acronym or abbreviation. Term definition

V
variable. (1) A storage place within an object for a data feature. The data feature is an object, such as number or date, stored as an attribute of the containing object. (2) A bean that receives an identity at run time. A variable by itself contains no data or program logic; it must be connected such that it receives run-time identity from a bean elsewhere in the application. versioned edition. An edition that has been versioned and can no longer be modified. versioning. The act of making an open edition a versioned edition; that is, making the edition read-only. view. (1) A visual bean, such as a window, push button, or entry field. (2) A visual representation that can display and change the underlying model objects of an application. Views are both the end result of developing an application and the basic unit of composition of user interfaces. Compare with visual bean. Contrast with model. visual bean. In the Visual Composition Editor, a bean that is visible to the end user in the graphical user interface. Compare with view. Contrast with nonvisual bean.

398

Developing Enterprise JavaBeans with VisualAge for Java

Draft Document for Review April 14, 1999 3:55 pm

5429abrv.fm

List of
IDL
interface definition language Internet Inter-ORB Protocol Information Management System interoperable object reference International Technical Support Organization Java archive Java Database Connectivity Java Developers Kit Java Native Interface Java Virtual Machine local area network managed object framework Multiple Virtual Storage National Language Support new technology Open Database Connectivity Object Management Group object modeling technique object-oriented object-oriented analysis object-oriented design Object Request Broker Operating System/2 object transaction service personal identification number rapid application development relational database management system Remote Method Invocation single-byte character set Software Developers Kit structured query language Transmission Control Protocol/Internet Protocol

Abbreviations
ANSI API ATM AWT CAE CB CICS CLI COM CORBA COS DB2 DBCS DBMS DL/I DLL DNS DRDA ECD ECI FTP GUI HTML HTTP IBM IDE
American National Standards Institute application programming interface automated teller machine Abstract Windowing Toolkit Client Access Enabler Component Broker Customer Information Control System call level interface Component Object Model Common Object Request Broker Architecture CORBA object services DATABASE 2 double-byte character set database management system Data Language/I dynamic link library domain name server Distributed Relational Database Architecture edit-compile-debug external call interface File Transfer Protocol graphical user interface Hypertext Markup Language Hypertext Transfer Protocol International Business Machines Corporation integrated development environment

IIOP IMS IOR ITSO JAR JDBC JDK JNI JVM LAN MOFW MVS NLS NT ODBC OMG OMT OO OOA OOD ORB OS/2 OTS PIN RAD RDBMS RMI SBCS SDK SQL TCP/IP

Copyright IBM Corp. 1999

399

5429abrv.fm
TP UOW URL WWW
transaction processing unit of work uniform resource locator World Wide Web

Draft Document for Review April 14, 1999 3:55 pm

400

Developing Enterprise JavaBeans with VisualAge for Java

Index
D
DCOM 7 Distributed Component Object Model see DCOM

E
EJB announcement 11 assembler 12 bean-managed persistence 14 components 13 container 13 container-managed persistence 15 deployer 12 Deployment Descriptor 13 entity beans 14 PrimaryKey 15 provider 12 server provider 13 session beans 14 system administrator 13

M
Method

Copyright IBM Corp. 1999

401

adding methods to EJBs 49

V
Visual Composition Editor palette 390

402

Developing Enterprise JavaBeans with VisualAge for Java

ITSO Redbook Evaluation


Developing Enterprise JavaBeans with VisualAge for Java SG24-5429-00 Your feedback is very important to help us maintain the quality of ITSO redbooks. Please complete this questionnaire and return it using one of the following methods: Use the online evaluation form found at http://www.redbooks.ibm.com Fax this form to: USA International Access Code + 1 914 432 8264 Send your comments in an Internet note to redbook@us.ibm.com Which of the following best describes you? _ Customer _ Business Partner _ Solution Developer _ None of the above

_ IBM employee

Please rate your overall satisfaction with this book using the scale: (1 = very good, 2 = good, 3 = average, 4 = poor, 5 = very poor) Overall Satisfaction Please answer the following questions: Was this redbook published in time for your needs? If no, please explain: Yes___ No___ __________

What other redbooks would you like to see published?

Comments/Suggestions:

(THANK YOU FOR YOUR FEEDBACK!)

Copyright IBM Corp. 1999

403

404

Developing Enterprise JavaBeans with VisualAge for Java

Developing Enterprise JavaBeans with VisualAge for Java

SG24-5429-00

SG24-5429-00 Printed in the U.S.A.

406

Developing Enterprise JavaBeans with VisualAge for Java

Das könnte Ihnen auch gefallen