Step 3: packaging and deploying the Beans

eploying an entity bean requires providing some extra information, in addition to that required for a session bean. This information is provided in the deployment descriptor ejb-jar.xml


<enterprise-beans>
  <entity>
    <description>Models a music CD</description>
    <ejb-name>CDBean</ejb-name>
    <home>com.web_tomorrow.cd.CDHome</home>
    <remote>com.web_tomorrow.cd.CD</remote>
    <ejb-class>com.web_tomorrow.cd.CDBean</ejb-class>
    <persistence-type>Container</persistence-type>
    <prim-key-class>java.lang.String</prim-key-class>
    <reentrant>False</reentrant>
    <cmp-field><field-name>id</field-name></cmp-field>
    <cmp-field><field-name>title</field-name></cmp-field>
    <cmp-field><field-name>artist</field-name></cmp-field>
    <cmp-field><field-name>type</field-name></cmp-field>
    <cmp-field><field-name>notes</field-name></cmp-field>
    <primkey-field>id</primkey-field>
  </entity>

<!-- more beans here -->

</entity-beans>

The listing above shows the section of ejb-jar.xml that is relevant to the CD Bean. It has the usual information about the classes that consitute the Bean, but it also specifies the type and name of the primary key, and the fields that are persistent. Note that in this case the `id' field gets listed twice: once as a persistent field and then again as the primary key field. It might be thought that specifying a field as a primary key would automatically make it persistent, but it doesn't. Leaving out the cmp-field definition for the primary key results in this error message at deployment time:

[JAWS] Initializing JAWS plugin for CDBean
[Container factory] java.lang.NoSuchFieldException: CASE_INSENSITIVE_ORDER
The deployment descriptor for the CDCollection class does not require any persistence information, but it does require an ejb-ref section; this indicates that the CDCollection Bean refers to CD Bean instances. The ejb-ref section lists the type of the CD Bean, and all its classes.


  <session>
  <description>Models a music CD collection</description>
  <ejb-name>CDCollectionBean</ejb-name>
  <home>com.web_tomorrow.cd.CDCollectionHome</home>
  <remote>com.web_tomorrow.cd.CDCollection</remote>
  <ejb-class>com.web_tomorrow.cd.CDCollectionBean</ejb-class>
  <ejb-ref>
    <ejb-ref-name>ejb/CD</ejb-ref-name>
    <ejb-ref-type>Entity</ejb-ref-type>
    <home>com.web_tomorrow.cd.CDHome</home>
    <remote>com.web_tomorrow.cd.CD</remote>
    <ejb-link>com.web_tomorrow.cd.CDBean</ejb-link>
  </ejb-ref>
</session>

In the jBoss run-time configuration file `jboss.xml' we should specify the type of configuration to be used by Beans, and their JNDI names, like this:


<entity>
  <ejb-name>CDBean</ejb-name>
  <jndi-name>cd/CD</jndi-name>
  <configuration-name>CMP EntityBean</configuration-name>
</entity>

<session>
  <ejb-name>CDCollectionBean</ejb-name>
  <jndi-name>cd/CDCollection</jndi-name>
  <configuration-name>Default Stateless SessionBean</configuration-name>
</session>

This says the `CDBean' uses the configuration `CMP EntityBean' and has the JNDI name `cd/CD'. `CDCollectionBean' uses the configuration `Default Stateless SessionBean' and has the JNDI name `cd/CDCollection'. Note that the method of specifying these configurations depends on the server.
       When packaging these Beans, don't forget to include the files ejb-jar.xml and jboss.jar in the directory META-INF.
       During deployment (simply copy the packaged beans to the `deploy' subdirectory of the jBoss directory) you should see a message like the following:

[Container factory] Deploying:file:/usr/lib/jboss/deploy/cd.jar
[Container factory] Deploying CDBean
[Container factory] Deploying CDCollectionBean
[JAWS] Initializing JAWS plugin for CDBean
[JAWS] Remove:DELETE FROM CDBean WHERE id=?
[JAWS] Drop:DROP TABLE CDBean
[JAWS] Create table:CREATE TABLE CDBean (notes VARCHAR(256),title
VARCHAR(256),artist VARCHAR(256),id VARCHAR(256),type VARCHAR(256))
[JAWS] Insert:INSERT INTO CDBean (notes,title,artist,id,type) VALUES
(?,?,?,?,?)
[JAWS] Select:SELECT notes,title,artist,id,type FROM CDBean WHERE id=?
[JAWS] Table CDBean exists
[Container factory] Started: CDBean
[Container factory] Bind ejb/CD to com.web_tomorrow.cd.CDBean
[Container factory] Started: CDCollectionBean
[Container factory] Bound CDBean to cd/CD
[Container factory] Bound CDCollectionBean to cd/CDCollection
[Container factory] Deployed application: file:/usr/lib/jboss/deploy/cd.jar
`JAWS' is the jBoss interface to the database engine. During deployment JAWS has deleted any existing table called `CDBean', then created a new CDBean table with the specified column layout. How does it know to use VARCHAR(256) for each field? It doesn't: it's guessing because we haven't provided any other information. During deployment, JAWS looks for a file called `jaws.xml'; if this file exists it is read to configure the names and geometry of the database tables. VARCHAR(256) is the default for String attributes. The default table name is the same as that of the Bean class, which is why we have ended up with a table called `CDBean'. This also can be over-ridden in jaws.xml. In practice, the JAWS defaults are adequate for most applications. However, there may be speed advantages to using fixed-length fields (e.g., CHAR(XX) rather than variable-length ones if at all possible.
       Note that it can be very difficult to change the number or names of columns in the table once there is data in it. jBoss gets very confused by this, as you would expect. When a CMP Bean is re-deployed, JAWS tries to write into its table all the data it had in its last deployment. If the table has different columns it probably won't be able to do that. This means that it is important to get the persistent fields thoroughly correct before starting to put real data into the application.

©1994-2003 Kevin Boone, all rights reserved