hibernate-orm/reference/en/modules/toolset_guide.xml

463 lines
19 KiB
XML

<chapter id="toolsetguide" revision="2">
<title>Toolset Guide</title>
<para>
Roundtrip engineering with Hibernate is possible using a set of Eclipse plugins,
commandline tools, as well as Ant tasks.
</para>
<para>
The <emphasis>Hibernate Tools</emphasis> currently include plugins for the Eclipse
IDE as well as Ant tasks for reverse engineering of existing databases:
</para>
<itemizedlist>
<listitem><para>
<emphasis>Mapping Editor:</emphasis> An editor for Hibernate XML mapping files,
supporting auto-completion and syntax highlighting. It also supports semantic
auto-completion for class names and property/field names, making it much more versatile than a normal XML editor.
</para></listitem>
<listitem><para>
<emphasis>Console:</emphasis> The console is a new view in Eclipse. In addition to
a tree overview of your console configurations, you also get an interactive view
of your persistent classes and their relationships. The console allows you to
execute HQL queries against your database and browse the result directly in
Eclipse.
</para></listitem>
<listitem><para>
<emphasis>Development Wizards:</emphasis> Several wizards are provided with the
Hibernate Eclipse tools; you can use a wizard to quickly generate Hibernate configuration
(cfg.xml) files, or you may even completely reverse engineer an existing database schema
into POJO source files and Hibernate mapping files. The reverse engineering wizard
supports customizable templates.
</para></listitem>
<listitem><para>
<emphasis>Ant Tasks:</emphasis>
</para></listitem>
</itemizedlist>
<para>
Please refer to the <emphasis>Hibernate Tools</emphasis> package and it's documentation
for more information.
</para>
<para>
However, the Hibernate main package comes bundled with an integrated tool (it can even
be used from "inside" Hibernate on-the-fly): <emphasis>SchemaExport</emphasis> aka
<literal>hbm2ddl</literal>.
</para>
<sect1 id="toolsetguide-s1" revision="2">
<title>Automatic schema generation</title>
<para>
DDL may be generated from your mapping files by a Hibernate utility. The generated
schema includes referential integrity constraints (primary and foreign keys) for
entity and collection tables. Tables and sequences are also created for mapped
identifier generators.
</para>
<para>
You <emphasis>must</emphasis> specify a SQL <literal>Dialect</literal> via the
<literal>hibernate.dialect</literal> property when using this tool, as DDL
is highly vendor specific.
</para>
<para>
First, customize your mapping files to improve the generated schema.
</para>
<sect2 id="toolsetguide-s1-2" revision="1">
<title>Customizing the schema</title>
<para>
Many Hibernate mapping elements define an optional attribute named <literal>length</literal>. You may set
the length of a column with this attribute. (Or, for numeric/decimal data types, the precision.)
</para>
<para>
Some tags also accept a <literal>not-null</literal> attribute (for generating a <literal>NOT NULL</literal>
constraint on table columns) and a <literal>unique</literal> attribute (for generating <literal>UNIQUE</literal>
constraint on table columns).
</para>
<para>
Some tags accept an <literal>index</literal> attribute for specifying the
name of an index for that column. A <literal>unique-key</literal> attribute
can be used to group columns in a single unit key constraint. Currently, the
specified value of the <literal>unique-key</literal> attribute is
<emphasis>not</emphasis> used to name the constraint, only to group the
columns in the mapping file.
</para>
<para>
Examples:
</para>
<programlisting><![CDATA[<property name="foo" type="string" length="64" not-null="true"/>
<many-to-one name="bar" foreign-key="fk_foo_bar" not-null="true"/>
<element column="serial_number" type="long" not-null="true" unique="true"/>]]></programlisting>
<para>
Alternatively, these elements also accept a child <literal>&lt;column&gt;</literal> element. This is
particularly useful for multi-column types:
</para>
<programlisting><![CDATA[<property name="foo" type="string">
<column name="foo" length="64" not-null="true" sql-type="text"/>
</property>]]></programlisting>
<programlisting><![CDATA[<property name="bar" type="my.customtypes.MultiColumnType"/>
<column name="fee" not-null="true" index="bar_idx"/>
<column name="fi" not-null="true" index="bar_idx"/>
<column name="fo" not-null="true" index="bar_idx"/>
</property>]]></programlisting>
<para>
The <literal>sql-type</literal> attribute allows the user to override the default mapping
of Hibernate type to SQL datatype.
</para>
<para>
The <literal>check</literal> attribute allows you to specify a check constraint.
</para>
<programlisting><![CDATA[<property name="foo" type="integer">
<column name="foo" check="foo > 10"/>
</property>]]></programlisting>
<programlisting><![CDATA[<class name="Foo" table="foos" check="bar < 100.0">
...
<property name="bar" type="float"/>
</class>]]></programlisting>
<table frame="topbot" id="schemattributes-summary" revision="2">
<title>Summary</title>
<tgroup cols="3">
<colspec colwidth="1*"/>
<colspec colwidth="1*"/>
<colspec colwidth="2.5*"/>
<thead>
<row>
<entry>Attribute</entry>
<entry>Values</entry>
<entry>Interpretation</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>length</literal></entry>
<entry>number</entry>
<entry>column length/decimal precision</entry>
</row>
<row>
<entry><literal>not-null</literal></entry>
<entry><literal>true|false</literal></entry>
<entry>specfies that the column should be non-nullable</entry>
</row>
<row>
<entry><literal>unique</literal></entry>
<entry><literal>true|false</literal></entry>
<entry>specifies that the column should have a unique constraint</entry>
</row>
<row>
<entry><literal>index</literal></entry>
<entry><literal>index_name</literal></entry>
<entry>specifies the name of a (multi-column) index</entry>
</row>
<row>
<entry><literal>unique-key</literal></entry>
<entry><literal>unique_key_name</literal></entry>
<entry>specifies the name of a multi-column unique constraint</entry>
</row>
<row>
<entry><literal>foreign-key</literal></entry>
<entry><literal>foreign_key_name</literal></entry>
<entry>
specifies the name of the foreign key constraint generated
for an association, use it on &lt;one-to-one>, &lt;many-to-one>,
&lt;key>, and &lt;many-to-many> mapping elements. Note that
<literal>inverse="true"</literal> sides will not be considered
by <literal>SchemaExport</literal>.
</entry>
</row>
<row>
<entry><literal>sql-type</literal></entry>
<entry><literal>column_type</literal></entry>
<entry>
overrides the default column type (attribute of
<literal>&lt;column&gt;</literal> element only)
</entry>
</row>
<row>
<entry><literal>check</literal></entry>
<entry>SQL expression</entry>
<entry>
create an SQL check constraint on either column or table
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
The <literal>&lt;comment&gt;</literal> element allows you to specify a comments
for the generated schema.
</para>
<programlisting><![CDATA[<class name="Customer" table="CurCust">
<comment>Current customers only</comment>
...
</class>]]></programlisting>
<programlisting><![CDATA[<property name="balance">
<column name="bal">
<comment>Balance in USD</comment>
</column>
</property>]]></programlisting>
<para>
This results in a <literal>comment on table</literal> or
<literal>comment on column</literal> statement in the generated
DDL (where supported).
</para>
</sect2>
<sect2 id="toolsetguide-s1-3">
<title>Running the tool</title>
<para>
The <literal>SchemaExport</literal> tool writes a DDL script to standard out and/or
executes the DDL statements.
</para>
<para>
<literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
<literal>org.hibernate.tool.hbm2ddl.SchemaExport</literal> <emphasis>options mapping_files</emphasis>
</para>
<table frame="topbot">
<title><literal>SchemaExport</literal> Command Line Options</title>
<tgroup cols="2">
<colspec colwidth="1.5*"/>
<colspec colwidth="2*"/>
<thead>
<row>
<entry>Option</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>--quiet</literal></entry>
<entry>don't output the script to stdout</entry>
</row>
<row>
<entry><literal>--drop</literal></entry>
<entry>only drop the tables</entry>
</row>
<row>
<entry><literal>--text</literal></entry>
<entry>don't export to the database</entry>
</row>
<row>
<entry><literal>--output=my_schema.ddl</literal></entry>
<entry>output the ddl script to a file</entry>
</row>
<row>
<entry><literal>--config=hibernate.cfg.xml</literal></entry>
<entry>read Hibernate configuration from an XML file</entry>
</row>
<row>
<entry><literal>--properties=hibernate.properties</literal></entry>
<entry>read database properties from a file</entry>
</row>
<row>
<entry><literal>--format</literal></entry>
<entry>format the generated SQL nicely in the script</entry>
</row>
<row>
<entry><literal>--delimiter=x</literal></entry>
<entry>set an end of line delimiter for the script</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
You may even embed <literal>SchemaExport</literal> in your application:
</para>
<programlisting><![CDATA[Configuration cfg = ....;
new SchemaExport(cfg).create(false, true);]]></programlisting>
</sect2>
<sect2 id="toolsetguide-s1-4">
<title>Properties</title>
<para>
Database properties may be specified
</para>
<itemizedlist spacing="compact">
<listitem>
<para>as system properties with <literal>-D</literal><emphasis>&lt;property&gt;</emphasis></para>
</listitem>
<listitem>
<para>in <literal>hibernate.properties</literal></para>
</listitem>
<listitem>
<para>in a named properties file with <literal>--properties</literal></para>
</listitem>
</itemizedlist>
<para>
The needed properties are:
</para>
<table frame="topbot">
<title>SchemaExport Connection Properties</title>
<tgroup cols="2">
<colspec colwidth="1.5*"/>
<colspec colwidth="2*"/>
<thead>
<row>
<entry>Property Name</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>hibernate.connection.driver_class</literal></entry>
<entry>jdbc driver class</entry>
</row>
<row>
<entry><literal>hibernate.connection.url</literal></entry>
<entry>jdbc url</entry>
</row>
<row>
<entry><literal>hibernate.connection.username</literal></entry>
<entry>database user</entry>
</row>
<row>
<entry><literal>hibernate.connection.password</literal></entry>
<entry>user password</entry>
</row>
<row>
<entry><literal>hibernate.dialect</literal></entry>
<entry>dialect</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
<sect2 id="toolsetguide-s1-5">
<title>Using Ant</title>
<para>
You can call <literal>SchemaExport</literal> from your Ant build script:
</para>
<programlisting><![CDATA[<target name="schemaexport">
<taskdef name="schemaexport"
classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
classpathref="class.path"/>
<schemaexport
properties="hibernate.properties"
quiet="no"
text="no"
drop="no"
delimiter=";"
output="schema-export.sql">
<fileset dir="src">
<include name="**/*.hbm.xml"/>
</fileset>
</schemaexport>
</target>]]></programlisting>
</sect2>
<sect2 id="toolsetguide-s1-6">
<title>Incremental schema updates</title>
<para>
The <literal>SchemaUpdate</literal> tool will update an existing schema with "incremental" changes.
Note that <literal>SchemaUpdate</literal> depends heavily upon the JDBC metadata API, so it will
not work with all JDBC drivers.
</para>
<para>
<literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis>
<literal>org.hibernate.tool.hbm2ddl.SchemaUpdate</literal> <emphasis>options mapping_files</emphasis>
</para>
<table frame="topbot">
<title><literal>SchemaUpdate</literal> Command Line Options</title>
<tgroup cols="2">
<colspec colwidth="1.5*"/>
<colspec colwidth="2*"/>
<thead>
<row>
<entry>Option</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>--quiet</literal></entry>
<entry>don't output the script to stdout</entry>
</row>
<row>
<entry><literal>--properties=hibernate.properties</literal></entry>
<entry>read database properties from a file</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
You may embed <literal>SchemaUpdate</literal> in your application:
</para>
<programlisting><![CDATA[Configuration cfg = ....;
new SchemaUpdate(cfg).execute(false);]]></programlisting>
</sect2>
<sect2 id="toolsetguide-s1-7">
<title>Using Ant for incremental schema updates</title>
<para>
You can call <literal>SchemaUpdate</literal> from the Ant script:
</para>
<programlisting><![CDATA[<target name="schemaupdate">
<taskdef name="schemaupdate"
classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
classpathref="class.path"/>
<schemaupdate
properties="hibernate.properties"
quiet="no">
<fileset dir="src">
<include name="**/*.hbm.xml"/>
</fileset>
</schemaupdate>
</target>]]></programlisting>
</sect2>
</sect1>
</chapter>