Managing Schema


When you deployed the ToDo application, JBoss created the tables required by the entity beans. This is JBoss's default behavior, but JBoss can be even more helpful during the stages of development when your beans are more volatile and are undergoing constant change.

When your entity beans change, your database schema also has to change. It's great that JBoss creates the schema for you, but what happens when you need the schema to change? You could delete the tables from the database and redeploy the application to force JBoss to re-create the tables.


Note: Keeping the database schema in sync with changing beans is always a huge drain on productivity.

Fortunately, you don't need to do anything quite so heavy-handed. JBoss provides several options for schema management. We've seen automatic schema creation so far, but JBoss also provides automatic schema deletion and migration options, if you ask for them.

How do I do that?

JBoss provides three schema management flags: create-table, remove-table, and alter-table. The create-table flag controls whether JBoss creates the required tables if they don't already exist when the application is deployed. The remove-table flag indicates whether JBoss should remove the tables for the application when the application is undeployed. Finally, the alter-table flag specifies whether JBoss should try to modify the table definition when the underlying bean changes.

You can set these three flags across the system, for a specific application, or for a specific entity bean or relation. The systemwide defaults are set in standardjbosscmp-jdbc.xml in the conf directory. If you look at the defaults section at the top of the file, you'll notice that create-table defaults to true, whereas alter-table and remove-table default to false.


Note: This is a common JBoss configuration pattern. JBoss systemwide defaults can be overridden by application defaults, and application defaults can be overridden for each bean. You can choose whichever scope is most appropriate for your needs.

It is generally not advisable to edit the systemwide configuration. If you want to change the schema policies, you can add the flags to your own jbosscmp-jdbc.xml file. You should place this deployment descriptor in the META-INF directory of an EJB jar file, alongside the ejb-jar.xml file.

You've already been operating with the create-table flag set to TRue, and you've seen JBoss create the database tables for you. Now we'll turn on the remove-table and alter-tableflags. This change causes JBoss to remove the tables when it undeploys the application. It also causes JBoss to upgrade the schema should it find the tables already there.

That condition shouldn't occur if JBoss is removing the tables before undeploying the previous version of the application. However, the tables could exist if JBoss is stopped abruptly, perhaps due to a hardware or JVM failure, or if the previous version of the application doesn't have the remove-table flag set. The latter will be the case when you deploy the application for the first time with these flags set.


Note: If you want to run the examples against a different database, make sure you set the database options that you saw in Chapter 4.

To set the flag, you'll need a jbosscmp-jdbc.xml file with all three flags set to true:

     <!DOCTYPE jbosscmp-jdbc PUBLIC               "-//JBoss//DTD JBOSSCMP-JDBC 4.0//EN"               "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_4_0.dtd">     <jbosscmp-jdbc>         <defaults>             <create-table>true</create-table>             <alter-table>true</alter-table>             <remove-table>true</remove-table>         </defaults>     </jbosscmp-jdbc> 

You'll find this file in the etc/cmp directory of the ToDo project. To make sure it is included in the deployed application, set the optional.dd flag to cmp when building:

     [todo]$ ant -Doptional.dd=cmp main deploy 

When you deploy the application, nothing interesting should happen. Since remove-table was false and there have been no schema changes, JBoss will simply redeploy the application, as we've seen it do many times already. However, once you do that, the remove-table flag will be true, and you'll see JBoss remove the tables when the application is undeployed.

To undeploy the application, you need to remove it from the deploy directory. The undeploy target in build.xml will do that:


Note: The biggest drawback to removing the tables is that you will lose any data you had created. If your application requires seed data, you'll have to remember to populate the database again.
     [todo]$ ant undeploy     Buildfile: build.xml         undeploy:        [delete] Deleting: /tmp/jboss-4.0.2/server/default/deploy/todo.ear 

You can verify that JBoss removed the tables by launching the Hypersonic database manager and checking that the tables are indeed deleted. Or, if you still have CMP logging enabled, you can check the log messages to see the SQL statements issued.

If you redeploy the application, you'll see JBoss re-create the tables. That, of course, means that any tasks you had previously created are gone.

Now we'll explore the table modification capabilities. For that, you'll need to turn off remove-table. Edit jbosscmp-jdbc.xml as shown here:

     <!DOCTYPE jbosscmp-jdbc PUBLIC               "-//JBoss//DTD JBOSSCMP-JDBC 4.0//EN"               "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_4_0.dtd">     <jbosscmp-jdbc>         <defaults>             <create-table>true</create-table>             <alter-table>true</alter-table>             <remove-table>false</remove-table>         </defaults>     </jbosscmp-jdbc> 

Redeploy the application to make sure that it is in a state where the tables won't be removed. It will also be helpful to add some tasks in the application to see that your data is preserved, even through schema updates.

To change to the schema, we'll add a priority field to TaskBean. Doing that is quite painless. You'll need to add the following abstract getter and setter methods, with the appropriate XDoclet attributes, to TaskBean.java:

     /**           * @ejb.persistence       * @ejb.interface-method      */     public abstract int getPriority(  );             /** @ejb.interface-method */     public abstract void setPriority(int priority); 


Note: Modifying the schema works best when adding or removing fields.As you'll see shortly, type changes are not always possible.

Build and deploy the application again, just as you did earlier:

     [todo]$ ant -Doptional.dd=cmp main deploy 

JBoss has added a new priority column to the TASK table. You can verify it through the database manager. If you still have it running, you'll need to refresh the schema view by selecting Refresh Tree from the View menu. Schema updates are logged at the WARN level, so you will see a notice of the change in the console log:

     16:44:44,765 WARN  [Task] ALTER TABLE TASK ADD COLUMN priority INTEGER NOT     NULL 

For illustrative purposes, you can remove the getPriority and setPriority methods from TaskBean, returning it to its original state, and redeploy the application again. This time JBoss will notice that the field is missing and will remove the priority column:

     16:46:57,339 WARN  [Task] ALTER TABLE TASK DROP COLUMN PRIORITY 

What just happened

JBoss is able to help you not only rapidly deploy J2EE applications, but also keep up with rapid changes in your application. When JBoss was combined with XDoclet, you were able to add a persistent field to an entity bean in about 30 seconds. The database schema was updated, and the value object code was changed, making the field immediately accessible to the web tier.


Note: Unless you have strict database performance or integration issues, it is better not to lock in the schema too soon. Leaving your options open gives you maximum flexibility as a developer.


JBoss. A Developer's Notebook
JBoss: A Developers Notebook
ISBN: 0596100078
EAN: 2147483647
Year: 2003
Pages: 106

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net