Deploying 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
<?xml version="1.0"?> <ejb-jar> <display-name>MusicCDs</display-name> <enterprise-beans> <entity> <description>Models a music CD</description> <ejb-name>CDBean</ejb-name> <home>org.jboss.docs.cmp.cd.interfaces.CDHome</home> <remote>org.jboss.docs.cmp.cd.interfaces.CD</remote> <ejb-class>org.jboss.docs.cmp.cd.bean.CDBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.Integer</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> <session> <description>Models a music CD collection</description> <ejb-name>CDCollectionBean</ejb-name> <home>org.jboss.docs.cmp.cd.interfaces.CDCollectionHome</home> <remote>org.jboss.docs.cmp.cd.interfaces.CDCollection</remote> <ejb-class>org.jboss.docs.cmp.cd.bean.CDCollectionBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <ejb-ref> <ejb-ref-name>ejb/CD</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <home>org.jboss.docs.cmp.cd.interfaces.CDHome</home> <remote>org.jboss.docs.cmp.cd.interfaces.CD</remote> <ejb-link>CDBean</ejb-link> </ejb-ref> </session> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>CDBean</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar>
The first part of 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.
The second part of the listing is for the CDCollection session bean. It 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.
In the JBoss run-time configuration file "jboss.xml" we should specify the JNDI names of the Beans, like this:
<?xml version="1.0" encoding="UTF-8"?> <jboss> <secure>false</secure> <container-configurations /> <resource-managers /> <enterprise-beans> <session> <ejb-name>CDCollectionBean</ejb-name> <jndi-name>cd/CDCollection</jndi-name> <configuration-name></configuration-name> </session> <entity> <ejb-name>CDBean</ejb-name> <jndi-name>cd/CD</jndi-name> <configuration-name></configuration-name> </entity> </enterprise-beans> </jboss>
This says the "CDBean" has the JNDI name "cd/CD" and "CDCollectionBean" has the JNDI name "cd/CDCollection".
To compile and package the EJBs, run "ant cmp-cd-compile". It compiles the sources and create an EJB jar file ready for deployment.
During deployment (simply copy "documentation-example/build-examples/cmp-cd/ejb/cd.jar" to the "deploy" subdirectory of the JBoss directory) you should see a message like the following:
[Default] JBoss 2.2.2 Started in 0m:5s [Auto deploy] Auto deploy of file:/C:/Projects/jbosscvs22/jboss/dist/deploy/cd.jar [J2EE Deployer Default] Deploy J2EE application: file:/C:/Projects/jbosscvs22/jboss/dist/deploy/cd.jar [J2EE Deployer Default] Create application cd.jar [J2EE Deployer Default] install module cd.jar [Container factory] Deploying:file:/C:/Projects/jbosscvs22/jboss/dist/tmp/deploy/Default/cd.jar [Verifier] Verifying file:/C:/Projects/jbosscvs22/jboss/dist/tmp/deploy/Default/cd.jar/ejb1001.jar [Container factory] Deploying CDBean [Container factory] Deploying CDCollectionBean [JAWS] Created table 'CDBean' successfully. [Bean Cache] Cache policy scheduler started [Container factory] Deployed application: file:/C:/Projects/jbosscvs22/jboss/dist/tmp/deploy/Default/cd.jar [J2EE Deployer Default] J2EE application: file:/C:/Projects/jbosscvs22/jboss/dist/deploy/cd.jar is deployed.
"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 during developement. 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.