Schema Management in Hibernate
One of Hibernate's most useful features is the automatic generation of schema manipulation commands. This feature, sometimes referred to as the ability to generate Data Definition Language (DDL) scripts, makes it possible (given a valid *.hbm.xml file) to create, update, and even drop tables in a target database. You can do this at runtime, during development, or via scripts generated for later use by a system administrator—an invaluable capability if you expect to support multiple target databases (during either development or deployment) or have a high degree of database schema change.
Hibernate supports two basic forms of DDL generation, update and export. Update is generally used within an application, targeting a specific database that may already contain a portion of the schema (and hence application data) but is missing schema components required by a new application. Export is used to generate the schema from scratch; it is especially useful if the application is not allowed to directly execute DDL (because, say, a database administrator is expected to perform these tasks).
Updating an Existing Schema
The tool net.sf.hibernate.tool.hbm2ddl.SchemaUpdate allows an application to bring a schema up to date with the expected schema based on a set of *.hbm.xml files. Typically, this is used to address a situation in which an incremental update to an application requires a relatively minor change, such as a new property.
Consider, for example, an application with a user object (and corresponding user table). You've decided to add a property to the user object to track the user's country code (previously the application only supported U.S. addresses). You make the change to your *.hbm.xml file and the corresponding Java code, and now would like to reflect the change in the deployed database. This can be done either from the command line, from an Ant task, or embedded within your application.
SchemaUpdate relies heavily on metadata returned by a database driver to understand the existing schema. For this reason, the ability of SchemaUpdate to operate properly can vary from driver to driver (and database to database). If you are unable to use SchemaUpdate with your preferred database, you may wish to use the SchemaExport tool (described later in this chapter) instead.
Schema Updates from within an Application
Listing 11.1 shows an example of SchemaUpdate embedded within an application. Note that a Configuration object is required, but a Session is not (obviously, you should perform any schema manipulation before working with the database).
Example 11.1. SchemaUpdate Example
package com.cascadetg.ch11; /** Various Hibernate-related imports */ import net.sf.hibernate.*; import net.sf.hibernate.cfg.*; import net.sf.hibernate.tool.hbm2ddl.SchemaUpdate; public class SchemaUpdaterExample { /** We use this session factory to create our sessions */ public static SessionFactory sessionFactory; public static void main(String[] args) { initialization(); } /** * Loads the Hibernate configuration information, sets up * the database and the Hibernate session factory. */ public static void initialization() { System.out.println("initialization"); try { Configuration myConfiguration = new Configuration(); myConfiguration .addClass(com.cascadetg.ch03.Owner.class); myConfiguration .addClass(com.cascadetg.ch03.Artifact .class); // Load the *.hbm.xml files as set in the // config, and set the dialect. new SchemaUpdate(myConfiguration) .execute(true, true); } catch (Exception e) { e.printStackTrace(); } } }
Command Line Schema Updates
To use SchemaUpdate from the command line, you have to use the command java net.sf.hibernate.tool.hbm2ddl.SchemaUpdate, passing in one or more of the command-line options shown in Table 11.1, followed by the path to the *.hbm.xml files.
Table 11.1. SchemaUpdate Command-Line Options
--quiet |
Echo the script to the console |
--properties= |
Specify the hibernate.properties file |
filename.properties |
|
--config= |
Specify the hibernate.cfg.xml file |
filename.cfg.xml |
|
--text |
Do not execute the update |
--naming= fully.qualified.class.name |
Specify the naming policy to use (Hibernate ships with net.sf.hibernate.cfg.Default NamingStrategy (prefers mixed case) and net.sf.hibernate.cfg.ImprovedNamingStrategy (prefers underscores). |
Ant Task Schema Updates
In addition to the runtime and command-line options, you can also use a build-time Ant task, as shown in Listing 11.2.
Example 11.2. SchemaUpdate Ant Task
<target name="schemaupdate"> <taskdef name="schemaupdate" classname="net.sf.hibernate.tool.hbm2ddl .SchemaUpdateTask" classpathref="class.path"/> <schemaupdate properties="hibernate.properties" quiet="no"> <fileset dir="src"> <include name="**/*.hbm.xml"/> </fileset> </schemaupdate> </target>