Creating and Deploying Stateless Session Beans and CMP Entity Beans, Page 3
You probably will never believe this, but we are finished with the source code; the only things left are the configuration files for our JAR, WAR, and EAR. But stop! We also need to create a MySQL database, a user for this database, and create a table "for" our entity beans. For this purpose, you can use MySQL Control Center tool (if you are using MySQL on a Windows computer) or the simple mysqladmin tool. Of course, you also can just simply use the next SQL queries to create the database, new user, and table. Here they are:
CREATE DATABASE jbossdb; INSERT INTO mysql.db VALUES ( 'localhost', 'jbossdb', 'userjboss', 'Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y'); INSERT INTO mysql.user VALUES( 'localhost', 'userjboss', password('zzz'), 'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N', 'N','N','N','N','N','','','','',0,0,0);
These queries will help you to create the database (first query), make user userjboss able to work with the newly created database jbossdb (second query), and create this new user userjboss with a password of zzz (third query).
Now, use the following query to create the table:
USE jbossdb; CREATE TABLE story ( story_id integer, pub_date timestamp );
Okay; now databases, user, tables—everything seems to be ready. Let's continue with the configuration files for JBoss. We need to create src/WEB-INF/web.xml for Tomcat (which is with JBoss). Here it is:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app />
It's empty, yes. We are using JSP, and do not have something to configure and to put into the Web container's configuration file. But we need to have it because it's required by the J2EE spec (of course, you know that!).
Now, we will create the next configuration files—src/META-INF/application.xml:
<?xml version="1.0" ?> <!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN" "http://java.sun.com/j2ee/dtds/application_1_2.dtd"> <application> <display-name>Teste and Story</display-name> <!-- EJB module --> <module> <ejb>teste-ejb.jar</ejb> </module> <!-- Web module --> <module> <web> <web-uri>teste.war</web-uri> <context-root>teste</context-root> </web> </module> </application>
and the configuration file—src/META-INF/jboss.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 3.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_3_0.dtd"> <jboss> <enterprise-beans> <session> <ejb-name>Teste</ejb-name> <jndi-name>ejb/Example/Teste</jndi-name> </session> <entity> <ejb-name>Story</ejb-name> <jndi-name>ejb/Example/Story</jndi-name> </entity> </enterprise-beans> <resource-managers /> </jboss>
Here, we define JNDI names for our session stateless bean and CMP entity bean. The names are pretty easy, so if you even never saw this configuration file before, you will be able to understand everything using your own simple logic.
The next configuration file is—src/META-INF/ejb-jar.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> <description>Teste and Story</description> <display-name>Teste and Story</display-name> <enterprise-beans> <session> <display-name>Teste Session Stateless Bean</display-name> <ejb-name>Teste</ejb-name> <home>teste.TesteHome</home> <remote>teste.Teste</remote> <ejb-class>teste.TesteBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> <entity> <display-name>Story Entity CMP Bean</display-name> <ejb-name>Story</ejb-name> <home>teste.StoryHome</home> <remote>teste.Story</remote> <ejb-class>teste.StoryBean</ejb-class> <reentrant>False</reentrant> <persistence-type>Container</persistence-type> <cmp-version>2.x</cmp-version> <abstract-schema-name>story</abstract-schema-name> <primkey-field>storyId</primkey-field> <prim-key-class>java.lang.Integer</prim-key-class> <cmp-field><field-name>storyId</field-name></cmp-field> <cmp-field><field-name>pubDate</field-name></cmp-field> </entity> </enterprise-beans> <assembly-descriptor /> </ejb-jar>
I want you to pay attention to the <entity> section. Just take a look and keep in your mind the last four lines in this section. We are defining the primary key, and describing fields of our entity bean.
Here is next configuration file—src/META-INF/jbosscmp-jdbc.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jbosscmp-jdbc PUBLIC "-//JBoss//DTD JBOSSCMP-JDBC 3.0//EN" "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_3_0.dtd"> <jbosscmp-jdbc> <defaults> <datasource>java:/MySqlDS</datasource> <datasource-mapping>mySQL</datasource-mapping> <create-table>false</create-table> <remove-table>false</remove-table> <pk-constraint>true</pk-constraint> <preferred-relation-mapping>foreign-key</preferred-relation-mapping> </defaults> <enterprise-beans> <entity> <ejb-name>Story</ejb-name> <table-name>story</table-name> <cmp-field> <field-name>storyId</field-name> <column-name>story_id</column-name> <not-null/> </cmp-field> <cmp-field> <field-name>pubDate</field-name> <column-name>pub_date</column-name> <not-null/> </cmp-field> </entity> </enterprise-beans> </jbosscmp-jdbc>
Don't worry about the first part of this file, but again, pay attention to the bottom part. Here, we are defining what each field from entity bean means compared to the database table. So, as you can see, we are saying that the storyId field is story_id column from our table, and pubDate is pub_date in the database. Besides, all descriptions of fields are informative enough, and do not demand further explanation. Certainly, for a deeper understanding of their essence, you should study the EJB specification, but that's beyond the scope of this article.
And one last configuration file is src/META-INF/mysql-ds.xml. You can take it from C:\jboss-3.2.3\docs\examples\jca\mysql-ds.xml (we assume that JBoss is installed in this directory) and modify it to have the correct database name, user's name, and password. Or, you can just use the following one:
<?xml version="1.0" encoding="UTF-8"?> <!-- ========================================================== --> <!-- --> <!-- JBoss Server Configuration --> <!-- --> <!-- ========================================================== --> <!-- $Id: mysql-ds.xml,v 1.1 2002/07/22 22:57:24 d_jencks Exp $ --> <!-- ========================================================== --> <!-- Datasource config for MySQL using 2.0.11 driver --> <!-- ========================================================== --> <datasources> <local-tx-datasource> <jndi-name>MySqlDS</jndi-name> <connection-url>jdbc:mysql://localhost:3306/jbossdb </connection-url> <driver-class>org.gjt.mm.mysql.Driver</driver-class> <user-name>userjboss</user-name> <password>zzz</password> </local-tx-datasource> </datasources>
Well, we are almost done. We need to compile everything, create JAR, WAR, and EAR, and deploy. Please check that JBoss is running, so you will see in its logs how everything will be deployed. Change the directory to the root directory where you placed all files, where build.xml is located, and type:
If everything was done correctly, you should see the same screen as the one below:
Please check your JBoss logs and you will see that everything was deployed correctly (like below):
This is a really huge portion of different debug information; do not worry about understanding it all. Just check that everything was deployed correctly, with no errors. And now, at least, when everything is deployed, you can open your favourite browser and type this next URL, http://localhost:8080/teste/index1.jsp, and you will see the following screen:
Then, type http://localhost:8080/teste/index2.jsp and you will get almost the same screen (yup, I've run this page many times, so I already have a lot of entities created!). On the left, and in bold, you will see the entities' ID and the creation date; all fields that have an entity bean.
Of course, now you will want to check that these entities "forced" to create equal records in the MySQL database. If you will execute any database client and execute the next query:
SELECT * FROM jbossdb.story;
you will see the following:
Oh, well! My congratulations; we succeeded! As you can see, applications that use CMP entity beans quickly become complex. The source code itself remains simple and easy, but the configuration files for the application server still make problems for newbies and even for rather experienced developers. But, from my own experience, I know that sometimes it's much easier to see something in practice, force it to work, and only after that get deeper into understanding all the parts.
I hope that this article will help you to understand how to use the JBoss application server in practice, how to deploy a session bean, and how to make a CMP entity bean work with help of MySQL. EJB technology possesses a lot of advantages and various unbelievable opportunities. It is important to learn how to use them in practice, even with the help of the simplest applications.