Many small improvements
git-svn-id: https://svn.jboss.org/repos/hibernate/trunk/Hibernate3/doc@5364 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
a8b37ee2f2
commit
7ca1999a26
|
@ -250,6 +250,11 @@
|
|||
<para>
|
||||
Consult the JBoss AS user guide for more information about these options.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another feature available as a JMX service are runtime Hibernate statistics. See
|
||||
<xref linkend="configuration-optional-statistics"/>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="architecture-jca" revision="1">
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<chapter id="mapping">
|
||||
<title>Basic O/R Mapping</title>
|
||||
|
||||
<sect1 id="mapping-declaration">
|
||||
<sect1 id="mapping-declaration" revision="1">
|
||||
<title>Mapping declaration</title>
|
||||
|
||||
<para>
|
||||
Object/relational mappings are defined in an XML document. The mapping document
|
||||
is designed to be readable and hand-editable. The mapping language is Java-centric,
|
||||
meaning that mappings are constructed around persistent class declarations, not
|
||||
table declarations.
|
||||
Object/relational mappings are usually defined in an XML document. The mapping
|
||||
document is designed to be readable and hand-editable. The mapping language is
|
||||
Java-centric, meaning that mappings are constructed around persistent class
|
||||
declarations, not table declarations.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -96,18 +96,20 @@
|
|||
|
||||
|
||||
|
||||
<sect2 id="mapping-declaration-doctype" revision="1">
|
||||
<sect2 id="mapping-declaration-doctype" revision="2">
|
||||
<title>Doctype</title>
|
||||
|
||||
<para>
|
||||
All XML mappings should declare the doctype shown. The actual DTD may be found
|
||||
at the URL above, in the directory <literal>hibernate-x.x.x/src/org/hibernate
|
||||
</literal> or in <literal>hibernate3.jar</literal>. Hibernate will always look for
|
||||
the DTD in its classpath first.
|
||||
the DTD in its classpath first. If you experience lookups of the DTD using an
|
||||
Internet connection, check your DTD declaration against the contents of your
|
||||
claspath.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-declaration-mapping" revision="2">
|
||||
<sect2 id="mapping-declaration-mapping" revision="3">
|
||||
<title>hibernate-mapping</title>
|
||||
|
||||
<para>
|
||||
|
@ -192,6 +194,16 @@
|
|||
<literal>auto-import="false"</literal>. Hibernate will throw an exception if you attempt
|
||||
to assign two classes to the same "imported" name.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that the <literal>hibernate-mapping</literal> element allows you to nest
|
||||
several persistent <literal><class></literal> mappings, as shown above.
|
||||
It is however good practice (and expected by some tools) to map only a single
|
||||
persistent class (or a single class hierarchy) in one mapping file and name
|
||||
it after the persistent superclass, e.g. <literal>Cat.hbm.xml</literal>,
|
||||
<literal>Dog.hbm.xml</literal>, or if using inheritance,
|
||||
<literal>Animal.hbm.xml</literal>.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
|
@ -510,9 +522,9 @@
|
|||
...]]></programlisting>
|
||||
|
||||
<para>
|
||||
Declare the tables to synchronize this entity, to ensure that auto-flush happens
|
||||
Declare the tables to synchronize this entity with, ensuring that auto-flush happens
|
||||
correctly, and that queries against the derived entity do not return stale data.
|
||||
The <literal><subselect></literal> is available as both an attribute and
|
||||
The <literal><subselect></literal> is available as both as an attribute and
|
||||
a nested mapping element.
|
||||
</para>
|
||||
|
||||
|
@ -915,7 +927,7 @@
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-declaration-discriminator" revision="2">
|
||||
<sect2 id="mapping-declaration-discriminator" revision="3">
|
||||
<title>discriminator</title>
|
||||
|
||||
<para>
|
||||
|
@ -997,11 +1009,13 @@
|
|||
that will be used to evaluate the type of a row:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[<discriminator formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end" type="integer"/>]]></programlisting>
|
||||
<programlisting><![CDATA[<discriminator
|
||||
formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end"
|
||||
type="integer"/>]]></programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-declaration-version">
|
||||
<sect2 id="mapping-declaration-version" revision="1">
|
||||
<title>version (optional)</title>
|
||||
|
||||
<para>
|
||||
|
@ -1062,7 +1076,7 @@
|
|||
</programlistingco>
|
||||
|
||||
<para>
|
||||
Version numbers may be of type <literal>long</literal>, <literal>integer</literal>,
|
||||
Version numbers may be of Hibernate type <literal>long</literal>, <literal>integer</literal>,
|
||||
<literal>short</literal>, <literal>timestamp</literal> or <literal>calendar</literal>.
|
||||
</para>
|
||||
|
||||
|
@ -1072,7 +1086,7 @@
|
|||
no matter what other <literal>unsaved-value</literal> strategies are specified.
|
||||
<emphasis>Declaring a nullable version or timestamp property is an easy way to avoid
|
||||
any problems with transitive reattachment in Hibernate, especially useful for people
|
||||
using assigned identiifers or composite keys!</emphasis>
|
||||
using assigned identifiers or composite keys!</emphasis>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
|
@ -1318,13 +1332,14 @@
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-declaration-manytoone" revision="2">
|
||||
<sect2 id="mapping-declaration-manytoone" revision="3">
|
||||
<title>many-to-one</title>
|
||||
|
||||
<para>
|
||||
An ordinary association to another persistent class is declared using a
|
||||
<literal>many-to-one</literal> element. The relational model is a
|
||||
many-to-one association. (Its really just an object reference.)
|
||||
many-to-one association: a foreign key in one table is referencing
|
||||
the primary key column(s) of the target table.
|
||||
</para>
|
||||
|
||||
<programlistingco>
|
||||
|
@ -1369,8 +1384,7 @@
|
|||
<literal>column</literal> (optional): The name of the foreign key column.
|
||||
This may also be specified by nested <literal><column></literal>
|
||||
element(s).
|
||||
|
||||
</para>
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="manytoone3">
|
||||
<para>
|
||||
|
@ -1437,11 +1451,10 @@
|
|||
</programlistingco>
|
||||
|
||||
<para>
|
||||
The <literal>cascade</literal> attribute permits the following values:
|
||||
<literal>all</literal>, <literal>save-update</literal>, <literal>delete</literal>,
|
||||
<literal>none</literal>. Setting a value other than <literal>none</literal>
|
||||
will propagate certain operations to the associated (child) object.
|
||||
See "Lifecycle Objects" below.
|
||||
Setting a value of the <literal>cascade</literal> attribute to not
|
||||
<literal>none</literal> will propagate certain operations to the
|
||||
associated object (usually in a parent/child fashion). See
|
||||
"Lifecycle Objects" discussed later.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -1621,7 +1634,7 @@
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-declaration-component" revision="1">
|
||||
<sect2 id="mapping-declaration-component" revision="2">
|
||||
<title>component, dynamic-component</title>
|
||||
|
||||
<para>
|
||||
|
@ -1692,15 +1705,15 @@
|
|||
accessed (requires build-time bytecode instrumentation).
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="component7">
|
||||
<para>
|
||||
<literal>optimistic-lock</literal> (optional - defaults to <literal>true</literal>):
|
||||
Specifies that updates to this component do or do not require acquisition of the
|
||||
optimistic lock. In other words, define if a version check should be made if this
|
||||
property is dirty.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
<callout arearefs="component7">
|
||||
<para>
|
||||
<literal>optimistic-lock</literal> (optional - defaults to <literal>true</literal>):
|
||||
Specifies that updates to this component do or do not require acquisition of the
|
||||
optimistic lock. In other words, define if a version check should be made if this
|
||||
property is dirty.
|
||||
</para>
|
||||
</callout>
|
||||
</programlistingco>
|
||||
|
||||
<para>
|
||||
|
@ -1716,17 +1729,18 @@
|
|||
|
||||
<para>
|
||||
The <literal><dynamic-component></literal> element allows a <literal>Map</literal>
|
||||
to be mapped as a component, where the property names refer to keys of the map.
|
||||
to be mapped as a component, where the property names refer to keys of the map, see
|
||||
<xref linken="components-dynamic"/>.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-declaration-subclass" revision="2">
|
||||
<sect2 id="mapping-declaration-subclass" revision="3">
|
||||
<title>subclass</title>
|
||||
|
||||
<para>
|
||||
Finally, polymorphic persistence requires the declaration of each subclass of
|
||||
the root persistent class. For the (recommended) table-per-class-hierarchy
|
||||
the root persistent class. For the table-per-class-hierarchy
|
||||
mapping strategy, the <literal><subclass></literal> declaration is used.
|
||||
</para>
|
||||
|
||||
|
@ -1783,6 +1797,10 @@
|
|||
fully qualified Java class name is used.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For information about inheritance mappings, see <xref linkend="inheritance"/>.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-declaration-joinedsubclass" revision="3">
|
||||
|
@ -1884,9 +1902,13 @@
|
|||
|
||||
</hibernate-mapping>]]></programlisting>
|
||||
|
||||
<para>
|
||||
For information about inheritance mappings, see <xref linkend="inheritance"/>.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-declaration-unionsubclass" revision="1">
|
||||
<sect2 id="mapping-declaration-unionsubclass" revision="2">
|
||||
<title>union-subclass</title>
|
||||
|
||||
<para>
|
||||
|
@ -1896,7 +1918,7 @@
|
|||
not absolutely necessary to explicitly map such inheritance hierarchies. You
|
||||
can simply map each class with a separate <literal><class></literal>
|
||||
declaration. However, if you wish use polymorphic associations (e.g. an association
|
||||
directed at the superclass of your hierarchy), you need to
|
||||
to the superclass of your hierarchy), you need to
|
||||
use the <literal><union-subclass></literal> mapping.
|
||||
</para>
|
||||
|
||||
|
@ -1954,6 +1976,10 @@
|
|||
No discriminator column or key column is required for this mapping strategy.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For information about inheritance mappings, see <xref linkend="inheritance"/>.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-declaration-join" revision="3">
|
||||
|
@ -2164,7 +2190,7 @@
|
|||
<sect1 id="mapping-types">
|
||||
<title>Hibernate Types</title>
|
||||
|
||||
<sect2 id="mapping-types-entitiesvalues">
|
||||
<sect2 id="mapping-types-entitiesvalues" revision="1">
|
||||
<title>Entities and values</title>
|
||||
|
||||
<para>
|
||||
|
@ -2186,16 +2212,12 @@
|
|||
<para>
|
||||
An entity's persistent state consists of references to other entities and
|
||||
instances of <emphasis>value</emphasis> types. Values are primitives,
|
||||
collections, components and certain immutable objects. Unlike entities, values
|
||||
(in particular collections and components) <emphasis>are</emphasis>
|
||||
persisted and deleted by reachability. Since value objects (and primitives) are
|
||||
persisted and deleted along with their containing entity they may not be
|
||||
independently versioned. Values have no independent identity, so they cannot be
|
||||
shared by two entities or collections.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All Hibernate types except collections support null semantics.
|
||||
collections (not whats inside a collection), components and certain immutable
|
||||
objects. Unlike entities, values (in particular collections and components)
|
||||
<emphasis>are</emphasis> persisted and deleted by reachability. Since value
|
||||
objects (and primitives) are persisted and deleted along with their containing
|
||||
entity they may not be independently versioned. Values have no independent
|
||||
identity, so they cannot be shared by two entities or collections.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -2203,14 +2225,43 @@
|
|||
entities. We will continue to do that. Strictly speaking, however, not all
|
||||
user-defined classes with persistent state are entities. A
|
||||
<emphasis>component</emphasis> is a user defined class with value semantics.
|
||||
A Java property of type <literal>java.lang.String</literal> also has value
|
||||
semantics. Given this definition, we can say that all types (classes) provided
|
||||
by the JDK have value type semantics in Java, while user-defined types may
|
||||
be mapped with entity or value type semantics. This decision is up to the
|
||||
application developer. A good hint for an entity class in a domain model are
|
||||
shared references to a single instance of that class, while composition or
|
||||
aggregation usually translates to a value type.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
We'll revisit both concepts throughout the documentation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The challenge is to map the Java type system (and the developers definition of
|
||||
entities and value types) to the SQL/database type system. The bridge between
|
||||
both systems is provided by Hibernate: for entities we use
|
||||
<literal><class></literal>, <literal><subclass<</literal> and so on.
|
||||
For value types we use <literal><property></literal>,
|
||||
<literal><component></literal>, etc, usually with a <literal>type</literal>
|
||||
attribute. The value of this attribute is the name of a Hibernate
|
||||
<emphasis>mapping type</emphasis>. Hibernate provides many mappings (for standard
|
||||
JDK value types) out of the box. You can write your own mapping types and implement your
|
||||
custom conversion strategies as well, as you'll see later.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All built-in Hibernate types except collections support null semantics.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="mapping-types-basictypes" revision="1">
|
||||
<sect2 id="mapping-types-basictypes" revision="2">
|
||||
<title>Basic value types</title>
|
||||
|
||||
<para>
|
||||
The <emphasis>basic types</emphasis> may be roughly categorized into
|
||||
The built-in <emphasis>basic mapping types</emphasis> may be roughly categorized into
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
|
@ -2422,6 +2473,10 @@
|
|||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<para>
|
||||
TODO: document parameterizable usertypes
|
||||
</para>
|
||||
|
||||
<sect2 id="mapping-types-anymapping" revision="2">
|
||||
<title>Any type mappings</title>
|
||||
|
@ -2544,7 +2599,7 @@
|
|||
<literal>hibernate-mapping</literal>. This allows you to extend a class hierachy just by adding
|
||||
a new mapping file. You must specify an <literal>extends</literal> attribute in the subclass mapping,
|
||||
naming a previously mapped superclass. Note: Previously this feature made the ordering of the mapping
|
||||
documents important. Since Hibernate 3, the ordering of mapping files does not matter when using the
|
||||
documents important. Since Hibernate3, the ordering of mapping files does not matter when using the
|
||||
extends keyword. The ordering inside a single mapping file still needs to be defined as superclasses
|
||||
before subclasses.
|
||||
</para>
|
||||
|
@ -2585,7 +2640,7 @@ public class Cat {
|
|||
private char sex;
|
||||
private float weight;
|
||||
|
||||
/**
|
||||
/*
|
||||
* @hibernate.id
|
||||
* generator-class="native"
|
||||
* column="CAT_ID"
|
||||
|
@ -2693,6 +2748,34 @@ public class Cat {
|
|||
package, as a separate download. Both EJB3 (JSR-220) and Hibernate3 metadata is supported.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This is an example of a POJO class annotated as an EJB entity bean:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[@Entity(access = AccessType.FIELD)
|
||||
public class Customer implements Serializable {
|
||||
|
||||
@Id;
|
||||
Long id;
|
||||
|
||||
String firstName;
|
||||
String lastName;
|
||||
Date birthday;
|
||||
|
||||
@Transient
|
||||
Integer age;
|
||||
|
||||
@Dependent
|
||||
private Address homeAddress;
|
||||
|
||||
@OneToMany(cascade=CascadeType.ALL,
|
||||
targetEntity="Order")
|
||||
@JoinColumn(name="CUSTOMER_ID")
|
||||
Set orders;
|
||||
|
||||
// Getter/setter and business methods
|
||||
}]]></programlisting>
|
||||
|
||||
<para>
|
||||
Note that support for JDK 5.0 Annotations (and JSR-220) is still work in progress and
|
||||
not completed.
|
||||
|
|
|
@ -797,16 +797,13 @@ hibernate.dialect = \
|
|||
</tgroup>
|
||||
</table>
|
||||
|
||||
<sect2 id="configuration-optional-dialects">
|
||||
<sect2 id="configuration-optional-dialects" revision="1">
|
||||
<title>SQL Dialects</title>
|
||||
|
||||
<para>
|
||||
You should always set the <literal>hibernate.dialect</literal> property to the correct
|
||||
<literal>org.hibernate.dialect.Dialect</literal> subclass for your database. This is not
|
||||
strictly essential unless you wish to use <literal>native</literal> or
|
||||
<literal>sequence</literal> primary key generation or pessimistic locking (with, eg.
|
||||
<literal>Session.lock()</literal> or <literal>Query.setLockMode()</literal>).
|
||||
However, if you specify a dialect, Hibernate will use sensible defaults for some of the
|
||||
<literal>org.hibernate.dialect.Dialect</literal> subclass for your database. If you
|
||||
specify a dialect, Hibernate will use sensible defaults for some of the
|
||||
other properties listed above, saving you the effort of specifying them manually.
|
||||
</para>
|
||||
|
||||
|
@ -931,23 +928,24 @@ hibernate.dialect = \
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="configuration-optional-cacheprovider" revision="1">
|
||||
<sect2 id="configuration-optional-cacheprovider" revision="2">
|
||||
<title>Second-level and query cache</title>
|
||||
|
||||
<para>
|
||||
The properties prefixed by <literal>hibernate.cache</literal>
|
||||
allow you to use a process or cluster scoped second-level cache system
|
||||
with Hibernate. See the "Performance" chapter for more details.
|
||||
with Hibernate. See the <xref linkend="performance-cache"/> for
|
||||
more details.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="configuration-optional-transactionstrategy" revision="1">
|
||||
<sect2 id="configuration-optional-transactionstrategy" revision="3">
|
||||
<title>Transaction strategy configuration</title>
|
||||
|
||||
<para>
|
||||
If you wish to use the Hibernate <literal>Transaction</literal> API instead
|
||||
of directly calling a particular transaction API, you must
|
||||
of directly calling a particular system transaction API, you must
|
||||
specify a factory class for <literal>Transaction</literal> instances by
|
||||
setting the property <literal>hibernate.transaction.factory_class</literal>.
|
||||
The <literal>Transaction</literal> API hides the underlying transaction
|
||||
|
@ -980,9 +978,10 @@ hibernate.dialect = \
|
|||
</para>
|
||||
|
||||
<para>
|
||||
If you wish to use a second-level cache for mutable data in a JTA environment, you must specify
|
||||
a strategy for obtaining the JTA <literal>TransactionManager</literal>, since J2EE does not
|
||||
standardize a single mechanism:
|
||||
Some features in Hibernate (i.e. the second level cache) require access to the
|
||||
JTA <literal>TransactionManager</literal> in a management environment. You have to
|
||||
specify how Hibernate should obtain a reference to the <literal>TransactionManager</literal>,
|
||||
since J2EE does not standardize a single mechanism:
|
||||
</para>
|
||||
|
||||
<table frame="topbot" id="jtamanagerlookup" revision="1">
|
||||
|
@ -1039,7 +1038,7 @@ hibernate.dialect = \
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="configuration-optional-jndi" revision="1">
|
||||
<sect2 id="configuration-optional-jndi" revision="2">
|
||||
<title>JNDI-bound <literal>SessionFactory</literal></title>
|
||||
|
||||
<para>
|
||||
|
@ -1066,7 +1065,8 @@ hibernate.dialect = \
|
|||
<para>
|
||||
Hibernate will automatically place the <literal>SessionFactory</literal> in JNDI after
|
||||
you call <literal>cfg.buildSessionFactory()</literal>. This means you will at least have
|
||||
this call in some startup code (or utility class) in your application.
|
||||
this call in some startup code (or utility class) in your application, unless you use
|
||||
JMX deployment with the <literal>HibernateService</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -1101,14 +1101,15 @@ hibernate.dialect = \
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="configuration-optional-statistics" revision="1">
|
||||
<sect2 id="configuration-optional-statistics" revision="2">
|
||||
<title>Hibernate statistics</title>
|
||||
|
||||
<para>
|
||||
If you enable <literal>hibernate.generate_statistics</literal>, Hibernate will
|
||||
expose a number of metrics that are useful when tuning a running system via
|
||||
<literal>SessionFactory.getStatistics()</literal>. Hibernate can even be configured
|
||||
to expose these statistics via JMX (see the website for details).
|
||||
to expose these statistics via JMX. Read the Javadoc of the interfaces in
|
||||
<literal>org.hibernate.stats</literal> for more information.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
@ -1177,8 +1178,8 @@ hibernate.dialect = \
|
|||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="configuration-xmlconfig" revision="1">
|
||||
<title>XML Configuration File</title>
|
||||
<sect1 id="configuration-xmlconfig" revision="2">
|
||||
<title>XML configuration file</title>
|
||||
|
||||
<para>
|
||||
An alternative approach to configuration is to specify a full configuration in
|
||||
|
@ -1216,6 +1217,11 @@ hibernate.dialect = \
|
|||
<mapping resource="org/hibernate/auction/Item.hbm.xml"/>
|
||||
<mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
|
||||
|
||||
<!-- cache settings -->
|
||||
<class-cache class="org.hibernate.auction.Item" usage="read-write"/>
|
||||
<class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
|
||||
<collection-cache class="org.hibernate.auction.Item.bids" usage="read-write"/>
|
||||
|
||||
</session-factory>
|
||||
|
||||
</hibernate-configuration>]]></programlisting>
|
||||
|
@ -1223,11 +1229,14 @@ hibernate.dialect = \
|
|||
<para>
|
||||
As you can see, the advantage of this approach is the externalization of the
|
||||
mapping file names to configuration. The <literal>hibernate.cfg.xml</literal>
|
||||
is also more convenient once you have to tune the Hibernate cache.
|
||||
is also more convenient once you have to tune the Hibernate cache. Note that is
|
||||
your choice to use either <literal>hibernate.properties</literal> or
|
||||
<literal>hibernate.cfg.xml</literal>, both are equivalent, except for the above
|
||||
mentioned benefits of using the XML syntax.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Configuring Hibernate is then as simple as
|
||||
With the XML configuration, starting Hibernate is then as simple as
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[SessionFactory sf = new Configuration().configure().buildSessionFactory();]]></programlisting>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
Hibernate works best if these classes follow some simple rules, also known
|
||||
as the Plain Old Java Object (POJO) programming model. However, Hibernate3
|
||||
allows you to express a domain model in other ways: using trees of
|
||||
<literal>Map</literal> instances, for example.
|
||||
<literal>Map</literal> instances, for example.
|
||||
</para>
|
||||
|
||||
<sect1 id="persistent-classes-pojo">
|
||||
|
@ -134,16 +134,16 @@ public class Cat {
|
|||
persistent classes must have a default constructor (which may be non-public) so
|
||||
Hibernate can instantiate them using <literal>Constructor.newInstance()</literal>.
|
||||
We recommend having a constructor with at least <emphasis>package</emphasis>
|
||||
visibility for runtime proxy generation in Hibernate.
|
||||
visibility for runtime proxy generation in Hibernate.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="persistent-classes-pojo-identifier">
|
||||
<sect2 id="persistent-classes-pojo-identifier" revision="1">
|
||||
<title>Provide an identifier property (optional)</title>
|
||||
|
||||
<para>
|
||||
<literal>Cat</literal> has a property called <literal>id</literal>. This property
|
||||
holds the primary key column of a database table. The property might have been called
|
||||
maps to the primary key column of a database table. The property might have been called
|
||||
anything, and its type might have been any primitive type, any primitive "wrapper"
|
||||
type, <literal>java.lang.String</literal> or <literal>java.util.Date</literal>. (If
|
||||
your legacy database table has composite keys, you can even use a user-defined class
|
||||
|
@ -165,7 +165,7 @@ public class Cat {
|
|||
<listitem>
|
||||
<para>
|
||||
Transitive reattachment for detached objects (cascade update) -
|
||||
see "Lifecycle Objects"
|
||||
see "Lifecycle Objects"
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
@ -190,8 +190,8 @@ public class Cat {
|
|||
</para>
|
||||
<para>
|
||||
You can persist <literal>final</literal> classes that do not implement an interface
|
||||
with Hibernate, but you won't be able to use proxies for lazy associationfetching -
|
||||
which will limit your options for performance tuning.
|
||||
with Hibernate, but you won't be able to use proxies for lazy association fetching -
|
||||
which will limit your options for performance tuning.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
|
@ -219,20 +219,20 @@ public class DomesticCat extends Cat {
|
|||
}]]></programlisting>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="persistent-classes-equalshashcode">
|
||||
<sect1 id="persistent-classes-equalshashcode" revision="1">
|
||||
<title>Implementing <literal>equals()</literal> and <literal>hashCode()</literal></title>
|
||||
|
||||
<para>
|
||||
You have to override the <literal>equals()</literal> and <literal>hashCode()</literal>
|
||||
methods if you
|
||||
</para>
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
intend to put instances of persistent classes in a <literal>Set</literal>
|
||||
(the recommended way to represent many-valued associations)
|
||||
<emphasis>and</emphasis>
|
||||
</para>
|
||||
<emphasis>and</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
|
@ -240,13 +240,13 @@ public class DomesticCat extends Cat {
|
|||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
<para>
|
||||
Hibernate guarantees equivalence of persistent identity (database row) and Java identity
|
||||
only inside a particular session scope. So as soon as we mix instances retrieved in
|
||||
different sessions, we must implement <literal>equals()</literal> and
|
||||
<literal>hashCode()</literal> if we wish to have meaningful semantics for
|
||||
<literal>Set</literal>s.
|
||||
only inside a particular session scope. So as soon as we mix instances retrieved in
|
||||
different sessions, we must implement <literal>equals()</literal> and
|
||||
<literal>hashCode()</literal> if we wish to have meaningful semantics for
|
||||
<literal>Set</literal>s.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -255,15 +255,20 @@ public class DomesticCat extends Cat {
|
|||
be the same database row, they are therefore equal (if both are added to a <literal>Set</literal>,
|
||||
we will only have one element in the <literal>Set</literal>). Unfortunately, we can't use that
|
||||
approach with generated identifiers! Hibernate will only assign identifier values to objects
|
||||
that are persistent, a newly created instance will not have any identifier value! We recommend
|
||||
implementing <literal>equals()</literal> and <literal>hashCode()</literal> using
|
||||
<emphasis>Business key equality</emphasis>.
|
||||
that are persistent, a newly created instance will not have any identifier value! Furthermore,
|
||||
if an instance is unsaved and currently in a <literal>Set</literal>, saving it will assign
|
||||
an identifier value to the object. If <literal>equals()</literal> and <literal>hashCode()</literal>
|
||||
are based on the identifier value, the hash code would change, breaking the contract of the
|
||||
<literal>Set</literal>. See the Hibernate website for a full discussion of this problem. Note
|
||||
that this is not a Hibernate issue, but normal Java semantics of object identity and equality.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Business key equality means that the <literal>equals()</literal>
|
||||
method compares only the properties that form the business key, a key that would
|
||||
identify our instance in the real world (a <emphasis>natural</emphasis> candidate key):
|
||||
We recommend implementing <literal>equals()</literal> and <literal>hashCode()</literal>
|
||||
using <emphasis>Business key equality</emphasis>. Business key equality means that the
|
||||
<literal>equals()</literal> method compares only the properties that form the business
|
||||
key, a key that would identify our instance in the real world (a
|
||||
<emphasis>natural</emphasis> candidate key):
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[public class Cat {
|
||||
|
@ -290,9 +295,15 @@ public class DomesticCat extends Cat {
|
|||
|
||||
}]]></programlisting>
|
||||
|
||||
<para>
|
||||
Note that a business key does not have to be as solid as a database
|
||||
primary key candidate. Immutable or unique properties are usually good
|
||||
candidates for a business key.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1 id="persistent-classes-dynamic" revision="1">
|
||||
<sect1 id="persistent-classes-dynamic" revision="2">
|
||||
<title>Dynamic models</title>
|
||||
|
||||
<para>
|
||||
|
@ -302,42 +313,42 @@ public class DomesticCat extends Cat {
|
|||
</para>
|
||||
|
||||
<programlisting><![CDATA[<hibernate-mapping>
|
||||
|
||||
|
||||
<dynamic-class entity-name="TestMap">
|
||||
|
||||
|
||||
<id name="id"
|
||||
type="long"
|
||||
column="ID">
|
||||
type="long"
|
||||
column="ID">
|
||||
<generator class="sequence"/>
|
||||
</id>
|
||||
|
||||
<property name="name"
|
||||
column="NAME"
|
||||
type="string"/>
|
||||
|
||||
<property name="address"
|
||||
column="ADDRESS"
|
||||
type="string"/>
|
||||
|
||||
<many-to-one name="parent"
|
||||
column="PARENT_ID"
|
||||
class="TestMap"/>
|
||||
|
||||
<bag name="children"
|
||||
inverse="true"
|
||||
lazy="false"
|
||||
cascade="all">
|
||||
|
||||
<property name="name"
|
||||
column="NAME"
|
||||
type="string"/>
|
||||
|
||||
<property name="address"
|
||||
column="ADDRESS"
|
||||
type="string"/>
|
||||
|
||||
<many-to-one name="parent"
|
||||
column="PARENT_ID"
|
||||
class="TestMap"/>
|
||||
|
||||
<bag name="children"
|
||||
inverse="true"
|
||||
lazy="false"
|
||||
cascade="all">
|
||||
<key column="PARENT_ID"/>
|
||||
<one-to-many class="TestMap"/>
|
||||
</bag>
|
||||
|
||||
|
||||
</dynamic-class>
|
||||
|
||||
</hibernate-mapping>]]></programlisting>
|
||||
|
||||
<para>
|
||||
At runtime, you just instantiate <literal>HashMap</literal>s and use
|
||||
the Hibernate entity name to refer to a particular type.
|
||||
the Hibernate entity name to refer to a particular type:
|
||||
</para>
|
||||
|
||||
<programlisting><![CDATA[Session s = openSession();
|
||||
|
|
Loading…
Reference in New Issue