- - -

A Very Brief EJB Tutorial


Adding Jars to the Enterprise Application

Simply copy the jar files to the folder representing the Enterprise Application. Refresh the Enterprise Applicaton project by switching to the 'J2EE Navigator' tree view, right-clicking and selecting 'Refresh'. Then use the J2EE perspective to select an EJB Module that references the jar file and select 'Open with JAR dependency Editor'. The jars will then be included in the exported ear file.


Creating a Server and Server Configuration

Using the J2EE View Perspective

  1. Select 'Servers' from the 'J2EE Heirarchy' tree view
  2. Right click and select 'New->Server and Server Configuration'
  3. Enter the 'Server Name' e.g. 'Test Server'
  4. Check that the 'Server Type' is 'WebSphere version 5.0 -> Test Environment'
  5. Select 'Finish'

Creating CMP Entity Beans

Refer to this article for more help.


Creating a Data Source

IndirectJNDILookup error

If you are getting the following error when attempting to deploy CMP entity beans, it is most likely that you have not defined a datasource for the server it is being deployed on or not specified the 'CMP Factory JNDI Name' for the CMP bean.

<code>An IndirectJNDILookup object was created with an empty name. Lookups using this object will fail.</code>

Open the j2ee perspective in Websphere Application Developer. Select the server you wish to configure from the Server leaf in the tree view. Right click and select 'Open'.

A JAAS alias needs setting up before creating the data source.

  1. Select the 'Security Tab'
  2. Select 'Add' 'JAAS Authentication Entries'
  3. Create an appropriate user entry for the database. E.g. Alias=Admin, User ID=root

Select the 'Data source' tab

  1. Select the 'Add' option against the JDBC Provider list.
  2. Select 'User Defined' for the database type.
  3. Click on the 'JDBC provider type' list to enable the 'Next' button.
  4. Enter the JDBC Provider name as 'MySQL'
  5. Enter the implementation class name as 'com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource'.
  6. Remove the existing db2 library from the classpath.
  7. Add the MySql JDBC library to the classpath using 'Add External Jars...' E.g. lib/mysql-connector-java-3.0.8-stable-bin.jar
  8. Select 'Finish'.

Add a data source.

  1. Select the 'MySQL JDBC provider'
  2. Select the 'Add' data source option.
  3. Select 'Next'
  4. Enter a data source name - e.g. MySQL Data Source
  5. Enter the jndi name. E.g. jdbc/MySQL - (This must match the JNDI name used for each CMP bean, case-significant. See below)
  6. Helper class name com.ibm.websphere.rsadapter.ConnectJDBCDataStoreHelper
  7. Purge policy, as appropriate
  8. Select the user alias created above for 'Container-managed authentication alias'. E.g. 'Admin'
  9. Tick - Use this data source in CMP
  10. Select 'Finish'

Define the resource properties for the data source

  1. Select the MySQL data source created above.
  2. Add a resource property named 'port' with value '3306'
  3. Add a resource property named 'databaseName' with the value set to your database name.

Save your changes. 1. Save the changes.

Creating a CMP Entity Bean

Select and existing EJB project or create a new one by selecting File->New->EJB Project from the main menu.

  1. Select the EJB Project in the J2EE Heirarchy view.
  2. Right click the EJB Project and select New->Enterprise Bean
  3. Select 'Next'
  4. Select 'Entity bean with container managed persistence (CMP) fields'
  5. Enter a bean name, e.g. 'TestEntity'
  6. Enter a default package name, e.g. 'test'
  7. Select 'Next'
  8. Enter a key class to represent the primary key. Accept the default if the primary key is not a simple java type. E.g. 'java.lang.String'. If it is a simple java type, enter the type as an Object. Note: you cannot use base types like 'long' - use java.lang.Long instead.
  9. Ideally, CMP beans should only implement a local interface and therefore only accessed by other enterprise beans that represent the business logic of the application.
  10. Select the 'CMP Attributes' 'Add' button.
  11. Enter attribute (or field) details.
  12. Select 'Apply' (The 'Close' button behaves like a 'Cancel' button. Press 'Apply' before 'Close')
  13. Select 'Finish'
  14. Open the 'Deployment Descriptor Editor' for the newly created bean by right clicking the bean name in the tree view and selecting 'Open With' etc.
  15. Select the attribute that forms the primary key and click 'Add'.
  16. Confirm the JNDI name has been set under 'WebSphere Bindings'. E.g. ejb/test/TestEntity
  17. Under WebSphere bindings, enter the CMP Factory JNDI Name, e.g. jdbc/MySQL that you entered above for the data source. Note: this is case-significant.
  18. Set the 'Container authorization type' to 'PerConnectionFactory'
  19. Save your changes

Defining Relationships

This section is incomplete, but relationships are defined using the deployment descriptor pages.

You must also set up foreign key relationships in the table mapping section (below).

Generate EJB to RDB Mapping

See also how to create these manually.

  1. Select the EJB project in the J2EE Hierarchy tree (Not the EJB)
  2. Right click and select 'Generate->EJB to RDM Mapping...'
  3. Select 'Create a new backend project'
  4. Select 'Next'
  5. Select 'Top Down'
  6. Select 'Next'
  7. Select 'MySQL, V3.23' as the 'Target Database'.
  8. Enter the desired MySQL database name, e.g. 'test'
  9. Leave the 'Schema Name' as NULLID
  10. Select 'Finish'
  11. Re-generate the deployment code for the EJB module by selecting the EJB Project, right clickand select 'Generate->Generate Deploy and RMIC Code'.
  12. Generate the EAR deployment code by selecting the enterprise application, right click and select 'Generate Deploy Code'.

Note: If there are any errors, they are flagged in the J2EE Navigator tree view not the heirarchy tree view.

Manually creating table mappings

Create table definition

Using the J2ee Hierarchy view:

  1. select the 'Maps' leaf from the tree under the appropriate EJB Module
  2. right click on the database leaf element and select 'New->Other'
  3. Select 'Data' from the left pane of the wizard
  4. Select 'Table Definition' from the right pane
  5. Select 'Next'
  6. Select the 'Database/schema' 'Browse' button and browse to the database definition. This will be somewhere under your module->META-INF->backends->myDatabase->mySchema
  7. Enter an appropriate table name
  8. Selelct 'Next'
  9. Add column definitions
  10. Select 'Finish'.

Create a new Schema Definition

Using the J2ee Hierarchy view:

  1. Double click the schema definition underneath the 'Maps' leaf in the tree view
  2. In the 'Enterprise Beans' pane of the Map view window, select the CMP bean to be mapped
  3. In the 'Tables' pane of the Map view window, select the table to be mapped
  4. Right click and select 'Create mapping'
  5. Select an attribute in the 'Enterprise Beans' pane, then Right click the corresponding table column in the 'Tables' pane and select 'Create Mapping'
  6. Alternatively drag an drop attributes from the 'Enterprise Beans' pane onto columns in the 'Tables' pane.
  7. Repeat for all attributes
  8. You must also create a mapping between enterprise bean relationships (setup using the deployment descriptor) and the corresponding foreign key in the table. This is done in the same way as mapping attributes to columns. (Note: you will not be able to successfully implement EJB QL queries until all these mappings are in place).

Creating Database and Tables

Run a command prompt and change to the directory containing Table.ddl which was created when we did the EJB to RDB mapping. E.g. TestEJB\ejbModule\META-INF\backends\MYSQLV3231.

Note that you can also generate Schema DDL from the EJB project. This puts Table.ddl in the META-INF directory.

Start mysql. E.g. c:\mysql\bin\mysql -u root

If necessary, create the database with the command:

  • create database test;

Make sure you change to the newly created database BEFORE running the script, otherwise all the tables will be created in the wrong database.

  • use test;

Check the script contents, then run the script using the '\.' command. Enter ? <return> to see a list of commands.

  • \. Table.ddl

Confirm table creation with:

  • show tables;

Creating a Session Bean

  1. Right click the EJB project in the heirarchy view and select 'New->Enterprise Bean'.
  2. Check the EJB Project is correct.
  3. Select 'Next'
  4. Select 'Session Bean'
  5. Enter a bean name, e.g. 'TestSession'
  6. Select 'Next'
  7. Default options are probably OK
  8. Select 'Finish'

Assuming, ultimately, code in this bean will access the CMP bean, you must create an EJB reference in the deployment descriptor.


Creating an EJB Reference

1 Double click the EJB Project to open the 'EJB Deployment Descriptor' 1 Select the 'References' tab 1 Select the bean that is making a call to another bean 1 Select 'Add' 1 Select the reference type. Ideally a session bean should be using a local interface on a CMP bean, so select 'EJB local reference' 1 Select 'Next' 1 Select 'Browse' 'Link' 1 Select the target EJB (e.g. TestEntity) from the 'Link' drop down list 1 Select 'OK' 1 Select 'Finish' 1 Save the changes with 'File->Save All' from the main menu


Jar Dependency Editor

  1. Open the jar dependency editor by right clicking the EJB Project in the heirarchy view and selecting 'Open With->JAR Dependency Editor'
  2. Under 'Dependencies' select any utility jars that are required by any of the enterprise beans. E.g. log4j.jar, junit.jar

Testing the Entity Bean

  1. Start the server by right clicking one of the enterprise beans and selecting 'Run on server'. Note: This method of starting the server is necessary at least for the first time. Other methods seem to fail to deploy the beans properly. Thereafter other means of starting the server should work fine.
  2. Select 'Use an existing server' and select the appropriate server.
  3. Tick 'Set server as project default (do not prompt)'
  4. Wait for the server to report 'Server server1 open for e-business' in the console window. Check the console log for any errors and correct them before continuing. There shouldn't be any.
  5. The universal test client will run (if server started with 'Run on Server).
  6. Alternatively, run the universal test client, either by selecting it from the server window by right clicking the server and selecting 'Run universal test client' or by pointing your browser at http://localhost:9080/UTC/initialize?port=2809
  7. Navigate the JNDI tree by selecting 'JNDI Explorer' or click the small 'JNDI Explorer' button in the top right hand corner of the applet.
  8. Clicking through [Local EJB beans] will navigate to those beans defined with local interfaces (ideally your CMP beans).

Clicking on a CMP bean will show the 'Bean Page' window. Clicking on the home inteface of a bean will show creation options. E.g. findByPrimaryKey. Clicking on the creation option may prompt for parameters then attempt to invoke an instance of the bean. Check the console window for errors. Often the cause of the error is not the first exception messages displayed. Scrolling down to '---- Begin backtrace for nested exception' usually displays the most appropriate exception.

You may get an error 'table xxx.t1 doesn't exist' - Hell. Create one with any old column names and keep WebSphere happy! In MySQL:

  • create table t1 (dummy varchar(1));

JNDI Trouble shooting

Note the WSAD 5.0 prefix for local interfaces is 'local:ejb/' Use the WSAD Universal Test Client using http://localhost:9080/UTC/ (or whatever port number the web server is running on) to see what the JNDI names are. The status bar in Internet Explorer shows the JNDI name when you mouse over the Objects in the JNDI explorer tree.

Using Local and Global JNDI references.

The recommended method of looking up EJBs since the EJB 1.1 specification is to use local JNDI lookups. Local JNDI lookups are prefixed by "java:comp/env". Local JNDI lookups can only be used within the J2EE container, e.g. from servlets and other EJBs. If accessing EJBs from a client, you must use the GLOBAL jndi reference.

When defining a reference from a servlet or EJB to another EJB, we define a <ejb-ref-name> which can then be used to perform the local JNDI lookup. The local name becomes the concatenation of "java:comp/env" and the <ejb-ref-name> e.g. assuming the <ejb-ref-name> is "ejb/MyEjb" the local JNDI name is "java:comp/env/ejb/MyEjb".

The EJB specification does not specify how the local name is mapped to a global name. Therefore this behaviour is vendor specific. WebSphere 5.0 uses a vendor specific deployment descriptor file named ibm-ejb-jar-bnd.xmi that maps the ejb-ref-name to the full global JNDI name.

In practice these are simply defined using the EJB Deployment Descriptor Editor. On the 'References' tab, the 'Name' field corresponds to <ejb-ref-name> and the 'WebSphere Bindings', 'JNDI name' is the global JNDI name of the bean being looked up. This global name must correspond to the JNDI name specified for the bean being looked up. The global JNDI names are defined on the 'Beans' tab.

I'm not certain this is necessary, but the local JNDI name defined for the ejb-ref-name should probably be named with a prefix of 'ejb/'.


log4j.properties file

Put it on the global classpath. Open the server configuration and select the 'Paths' tab.


See also: WebSphere


Frank Dean - 28 November 2003