HHH-5397 - Odds and ends from documentation merge : persistent_classes.xml
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@19978 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
17261e1e06
commit
249127b8c0
|
@ -2,10 +2,10 @@
|
|||
<!--
|
||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||
~
|
||||
~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
~ indicated by the @author tags or express copyright attribution
|
||||
~ statements applied by the authors. All third-party contributions are
|
||||
~ distributed under license by Red Hat Middleware LLC.
|
||||
~ distributed under license by Red Hat Inc.
|
||||
~
|
||||
~ This copyrighted material is made available to anyone wishing to use, modify,
|
||||
~ copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -27,39 +27,40 @@
|
|||
<!ENTITY % BOOK_ENTITIES SYSTEM "../HIBERNATE_-_Relational_Persistence_for_Idiomatic_Java.ent">
|
||||
%BOOK_ENTITIES;
|
||||
]>
|
||||
<chapter id="persistent-classes" revision="2">
|
||||
<title>Persistent Classes</title>
|
||||
|
||||
<para>Persistent classes are classes in an application that implement the
|
||||
entities of the business problem (e.g. Customer and Order in an E-commerce
|
||||
application). Not all instances of a persistent class are considered to be
|
||||
in the persistent state. For example, an instance can instead be transient
|
||||
or detached.</para>
|
||||
<chapter id="persistent-classes">
|
||||
<title>Persistent Classes</title>
|
||||
|
||||
<para>Hibernate works best if these classes follow some simple rules, also
|
||||
known as the Plain Old Java Object (POJO) programming model. However, none
|
||||
of these rules are hard requirements. Indeed, Hibernate3 assumes very little
|
||||
about the nature of your persistent objects. You can express a domain model
|
||||
in other ways (using trees of <literal>Map</literal> instances, for
|
||||
example).</para>
|
||||
<para>
|
||||
Persistent classes are classes in an application that implement the entities of the business problem
|
||||
(e.g. Customer and Order in an E-commerce application). The term "persistent" here means that the classes
|
||||
are able to be persisted, not that they are in the persistent state (see <xref linkend="objectstate-overview"/>
|
||||
for discussion).
|
||||
</para>
|
||||
|
||||
<section id="persistent-classes-pojo">
|
||||
<title>A simple POJO example</title>
|
||||
<para>
|
||||
Hibernate works best if these classes follow some simple rules, also known as the Plain Old Java Object (POJO)
|
||||
programming model. However, none of these rules are hard requirements. Indeed, Hibernate assumes very little
|
||||
about the nature of your persistent objects. You can express a domain model in other ways (using trees of
|
||||
<interfacename>java.util.Map</interfacename> instances, for example).
|
||||
</para>
|
||||
|
||||
<para>Most Java applications require a persistent class representing
|
||||
felines. For example:</para>
|
||||
<section id="persistent-classes-pojo">
|
||||
<title>A simple POJO example</title>
|
||||
|
||||
<programlisting role="JAVA">package eg;
|
||||
<example id="persistent-classes-pojo-example-cat">
|
||||
<title>Simple POJO representing a cat</title>
|
||||
<programlisting role="JAVA">package eg;
|
||||
import java.util.Set;
|
||||
import java.util.Date;
|
||||
|
||||
public class Cat {
|
||||
private Long id; // identifier
|
||||
private Long id; // identifier
|
||||
|
||||
private Date birthdate;
|
||||
private Color color;
|
||||
private char sex;
|
||||
private float weight;
|
||||
private Date birthdate;
|
||||
private Color color;
|
||||
private char sex;
|
||||
private float weight;
|
||||
private int litterId;
|
||||
|
||||
private Cat mother;
|
||||
|
@ -119,108 +120,137 @@ public class Cat {
|
|||
public Set getKittens() {
|
||||
return kittens;
|
||||
}
|
||||
|
||||
|
||||
// addKitten not needed by Hibernate
|
||||
public void addKitten(Cat kitten) {
|
||||
kitten.setMother(this);
|
||||
kitten.setLitterId( kittens.size() );
|
||||
kitten.setMother(this);
|
||||
kitten.setLitterId( kittens.size() );
|
||||
kittens.add(kitten);
|
||||
}
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>The four main rules of persistent classes are explored in more
|
||||
detail in the following sections.</para>
|
||||
|
||||
<section id="persistent-classes-pojo-constructor" revision="1">
|
||||
<title>Implement a no-argument constructor</title>
|
||||
<para>
|
||||
The four main rules of persistent classes are explored in more detail in the following sections.
|
||||
</para>
|
||||
|
||||
<para><literal>Cat</literal> has a no-argument constructor. All
|
||||
persistent classes must have a default constructor (which can be
|
||||
non-public) so that Hibernate can instantiate them using
|
||||
<literal>Constructor.newInstance()</literal>. It is recommended that you
|
||||
have a default constructor with at least <emphasis>package</emphasis>
|
||||
visibility for runtime proxy generation in Hibernate.</para>
|
||||
<section id="persistent-classes-pojo-constructor">
|
||||
<title>Implement a no-argument constructor</title>
|
||||
|
||||
<para>
|
||||
<classname>Cat</classname> has a no-argument constructor. All persistent classes must have a default
|
||||
constructor (which can be non-public) so that Hibernate can instantiate them using
|
||||
<literal><classname>java.lang.reflect.Constructor</classname>.newInstance()</literal>. It is recommended
|
||||
that this constructor be defined with at least <emphasis>package</emphasis> visibility in order for
|
||||
runtime proxy generation to work properly.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="persistent-classes-pojo-identifier" revision="2">
|
||||
<title>Provide an identifier property</title>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Historically this was considered option. While still not (yet) enforced, this should be considered
|
||||
a deprecated feature as it will be completely required to provide a identifier property in an
|
||||
upcoming release.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
<classname>Cat</classname> has a property named <literal>id</literal>. This property maps to the
|
||||
primary key column(s) of the underlying database table. The type of the identifier property can
|
||||
be any "basic" type (see <xref linkend="types.value.basic"/>). See <xref linkend="components-compositeid"/>
|
||||
for information on mapping composite (multi-column) identifiers.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Identifiers do not necessarily need to identify column(s) in the database physically defined
|
||||
as a primary key. They should just identify columns that can be used to uniquely identify rows
|
||||
in the underlying table.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
We recommend that you declare consistently-named identifier properties on persistent classes and that you use
|
||||
a nullable (i.e., non-primitive) type.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="persistent-classes-pojo-final">
|
||||
<title>Prefer non-final classes (semi-optional)</title>
|
||||
|
||||
<para>
|
||||
A central feature of Hibernate, <emphasis>proxies</emphasis> (lazy loading), depends upon the
|
||||
persistent class being either non-final, or the implementation of an interface that declares all public
|
||||
methods. You can persist <literal>final</literal> classes that do not implement an interface with
|
||||
Hibernate; you will not, however, be able to use proxies for lazy association fetching which will
|
||||
ultimately limit your options for performance tuning. To persist a <literal>final</literal>
|
||||
class which does not implement a "full" interface you must disable proxy generation. See
|
||||
<xref linkend="persistent-classes-pojo-final-example-disable-proxies-xml"/> and
|
||||
<xref linkend="persistent-classes-pojo-final-example-disable-proxies-ann"/>.
|
||||
</para>
|
||||
|
||||
<example id="persistent-classes-pojo-final-example-disable-proxies-xml">
|
||||
<title>Disabling proxies in <literal>hbm.xml</literal></title>
|
||||
<programlisting role="XML"><![CDATA[<class name="Cat" lazy="false"...>...</class>]]></programlisting>
|
||||
</example>
|
||||
|
||||
<example id="persistent-classes-pojo-final-example-disable-proxies-ann">
|
||||
<title>Disabling proxies in annotations</title>
|
||||
<programlisting role="JAVA"><![CDATA[@Entity @Proxy(lazy=false) public class Cat { ... }]]></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
If the <literal>final</literal> class does implement a proper interface, you could alternatively tell
|
||||
Hibernate to use the interface instead when generating the proxies. See
|
||||
<xref linkend="persistent-classes-pojo-final-example-proxy-interface-xml"/> and
|
||||
<xref linkend="persistent-classes-pojo-final-example-proxy-interface-ann"/>.
|
||||
|
||||
</para>
|
||||
|
||||
<example id="persistent-classes-pojo-final-example-proxy-interface-xml">
|
||||
<title>Proxying an interface in <literal>hbm.xml</literal></title>
|
||||
<programlisting role="XML"><![CDATA[<class name="Cat" proxy="ICat"...>...</class>]]></programlisting>
|
||||
</example>
|
||||
|
||||
<example id="persistent-classes-pojo-final-example-proxy-interface-ann">
|
||||
<title>Proxying an interface in annotations</title>
|
||||
<programlisting role="JAVA"><![CDATA[@Entity @Proxy(proxyClass=ICat.class) public class Cat implements ICat { ... }]]></programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
You should also avoid declaring <literal>public final</literal> methods as this will again limit
|
||||
the ability to generate <emphasis>proxies</emphasis> from this class. If you want to use a
|
||||
class with <literal>public final</literal> methods, you must explicitly disable proxying. Again, see
|
||||
<xref linkend="persistent-classes-pojo-final-example-disable-proxies-xml"/> and
|
||||
<xref linkend="persistent-classes-pojo-final-example-disable-proxies-ann"/>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="persistent-classes-pojo-accessors">
|
||||
<title>Declare accessors and mutators for persistent fields (optional)</title>
|
||||
|
||||
<para>
|
||||
<classname>Cat</classname> declares accessor methods for all its persistent fields. Many other ORM
|
||||
tools directly persist instance variables. It is better to provide an indirection between the relational
|
||||
schema and internal data structures of the class. By default, Hibernate persists JavaBeans style
|
||||
properties and recognizes method names of the form <literal>getFoo</literal>, <literal>isFoo</literal>
|
||||
and <literal>setFoo</literal>. If required, you can switch to direct field access for particular
|
||||
properties.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Properties need <emphasis>not</emphasis> be declared public. Hibernate can persist a property declared
|
||||
with <literal>package</literal>, <literal>protected</literal> or <literal>private</literal> visibility
|
||||
as well.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="persistent-classes-pojo-identifier" revision="2">
|
||||
<title>Provide an identifier property (optional)</title>
|
||||
|
||||
<para><literal>Cat</literal> has a property called
|
||||
<literal>id</literal>. This property 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 use a user-defined class with properties of
|
||||
these types (see the section on composite identifiers later in the
|
||||
chapter.)</para>
|
||||
|
||||
<para>The identifier property is strictly optional. You can leave them
|
||||
off and let Hibernate keep track of object identifiers internally. We do
|
||||
not recommend this, however.</para>
|
||||
|
||||
<para>In fact, some functionality is available only to classes that
|
||||
declare an identifier property:</para>
|
||||
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>Transitive reattachment for detached objects (cascade update
|
||||
or cascade merge) - see <xref
|
||||
linkend="objectstate-transitive" /></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>Session.saveOrUpdate()</literal></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>Session.merge()</literal></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>We recommend that you declare consistently-named identifier
|
||||
properties on persistent classes and that you use a nullable (i.e.,
|
||||
non-primitive) type.</para>
|
||||
</section>
|
||||
|
||||
<section id="persistent-classes-pojo-final">
|
||||
<title>Prefer non-final classes (optional)</title>
|
||||
|
||||
<para>A central feature of Hibernate, <emphasis>proxies</emphasis>,
|
||||
depends upon the persistent class being either non-final, or the
|
||||
implementation of an interface that declares all public methods.</para>
|
||||
|
||||
<para>You can persist <literal>final</literal> classes that do not
|
||||
implement an interface with Hibernate. You will not, however, be able to
|
||||
use proxies for lazy association fetching which will ultimately limit
|
||||
your options for performance tuning.</para>
|
||||
|
||||
<para>You should also avoid declaring <literal>public final</literal>
|
||||
methods on the non-final classes. If you want to use a class with a
|
||||
<literal>public final</literal> method, you must explicitly disable
|
||||
proxying by setting <literal>lazy="false"</literal>.</para>
|
||||
</section>
|
||||
|
||||
<section id="persistent-classes-pojo-accessors" revision="2">
|
||||
<title>Declare accessors and mutators for persistent fields
|
||||
(optional)</title>
|
||||
|
||||
<para><literal>Cat</literal> declares accessor methods for all its
|
||||
persistent fields. Many other ORM tools directly persist instance
|
||||
variables. It is better to provide an indirection between the relational
|
||||
schema and internal data structures of the class. By default, Hibernate
|
||||
persists JavaBeans style properties and recognizes method names of the
|
||||
form <literal>getFoo</literal>, <literal>isFoo</literal> and
|
||||
<literal>setFoo</literal>. If required, you can switch to direct field
|
||||
access for particular properties.</para>
|
||||
|
||||
<para>Properties need <emphasis>not</emphasis> be declared public -
|
||||
Hibernate can persist a property with a default,
|
||||
<literal>protected</literal> or <literal>private</literal> get / set
|
||||
pair.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="persistent-classes-inheritance">
|
||||
<title>Implementing inheritance</title>
|
||||
|
||||
|
@ -447,44 +477,53 @@ dynamicSession.close()
|
|||
found in <xref linkend="xml" />.</para>
|
||||
</section>
|
||||
|
||||
<section id="persistent-classes-tuplizers" revision="1">
|
||||
<title>Tuplizers</title>
|
||||
|
||||
<para><literal>org.hibernate.tuple.Tuplizer</literal>, and its
|
||||
sub-interfaces, are responsible for managing a particular representation
|
||||
of a piece of data given that representation's
|
||||
<literal>org.hibernate.EntityMode</literal>. If a given piece of data is
|
||||
thought of as a data structure, then a tuplizer is the thing that knows
|
||||
how to create such a data structure and how to extract values from and
|
||||
inject values into such a data structure. For example, for the POJO entity
|
||||
mode, the corresponding tuplizer knows how create the POJO through its
|
||||
constructor. It also knows how to access the POJO properties using the
|
||||
defined property accessors.</para>
|
||||
<section id="persistent-classes-tuplizers" revision="1">
|
||||
<title>Tuplizers</title>
|
||||
|
||||
<para>There are two high-level types of Tuplizers, represented by the
|
||||
<literal>org.hibernate.tuple.entity.EntityTuplizer</literal> and
|
||||
<literal>org.hibernate.tuple.component.ComponentTuplizer</literal>
|
||||
interfaces. <literal>EntityTuplizer</literal>s are responsible for
|
||||
managing the above mentioned contracts in regards to entities, while
|
||||
<literal>ComponentTuplizer</literal>s do the same for components.</para>
|
||||
<para>
|
||||
<interfacename>org.hibernate.tuple.Tuplizer</interfacename> and its sub-interfaces are responsible for
|
||||
managing a particular representation of a piece of data given that representation's
|
||||
<classname>org.hibernate.EntityMode</classname>. If a given piece of data is thought of as a data
|
||||
structure, then a tuplizer is the thing that knows how to create such a data structure, how to extract
|
||||
values from such a data structure and how to inject values into such a data structure. For example, for
|
||||
the POJO entity mode, the corresponding tuplizer knows how create the POJO through its constructor.
|
||||
It also knows how to access the POJO properties using the defined property accessors.
|
||||
</para>
|
||||
|
||||
<para>Users can also plug in their own tuplizers. Perhaps you require that
|
||||
a <literal>java.util.Map</literal> implementation other than
|
||||
<literal>java.util.HashMap</literal> be used while in the dynamic-map
|
||||
entity-mode. Or perhaps you need to define a different proxy generation
|
||||
strategy than the one used by default. Both would be achieved by defining
|
||||
a custom tuplizer implementation. Tuplizer definitions are attached to the
|
||||
entity or component mapping they are meant to manage. Going back to the
|
||||
example of our customer entity <xref
|
||||
linkend="example-defining-tuplizer-using-annotations" /> shows how to
|
||||
configure tuplizers using annotations whereas <xref
|
||||
linkend="example-defining-tuplizer-using-mapping-file" /> shows how to do
|
||||
the same thing using Hibernate mapping files.</para>
|
||||
<para>
|
||||
There are two (high-level) types of Tuplizers:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<interfacename>org.hibernate.tuple.entity.EntityTuplizer</interfacename> which is
|
||||
responsible for managing the above mentioned contracts in regards to entities
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<interfacename>org.hibernate.tuple.component.ComponentTuplizer</interfacename> which does the
|
||||
same for components
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<example id="example-defining-tuplizer-using-annotations">
|
||||
<title>Mapping custom tuplizers using annotations</title>
|
||||
<para>
|
||||
Users can also plug in their own tuplizers. Perhaps you require that
|
||||
<interfacename>java.util.Map</interfacename> implementation other than
|
||||
<classname>java.util.HashMap</classname> be used while in the dynamic-map entity-mode. Or perhaps you
|
||||
need to define a different proxy generation strategy than the one used by default. Both would be achieved
|
||||
by defining a custom tuplizer implementation. Tuplizer definitions are attached to the entity or component
|
||||
mapping they are meant to manage. Going back to the example of our <classname>Customer</classname> entity,
|
||||
<xref linkend="example-specify-custom-tuplizer-ann"/> shows how to specify a custom
|
||||
<interfacename>org.hibernate.tuple.entity.EntityTuplizer</interfacename> using annotations while
|
||||
<xref linkend="example-specify-custom-tuplizer-xml"/> shows how to do the same in <literal>hbm.xml</literal>
|
||||
</para>
|
||||
|
||||
<programlisting role="XML">@Entity
|
||||
<example id="example-specify-custom-tuplizer-ann">
|
||||
<title>Specify custom tuplizers in annotations</title>
|
||||
<programlisting role="JAVA">@Entity
|
||||
@Tuplizer(impl = DynamicEntityTuplizer.class)
|
||||
public interface Cuisine {
|
||||
@Id
|
||||
|
@ -499,13 +538,10 @@ public interface Cuisine {
|
|||
public Country getCountry();
|
||||
public void setCountry(Country country);
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title id="example-defining-tuplizer-using-mapping-file">Mapping custom
|
||||
tuplizers using mapping files</title>
|
||||
|
||||
<programlisting role="XML"><hibernate-mapping>
|
||||
</example>
|
||||
<example id="example-specify-custom-tuplizer-xml">
|
||||
<title>Specify custom tuplizers in <literal>hbm.xml</literal></title>
|
||||
<programlisting role="XML"><hibernate-mapping>
|
||||
<class entity-name="Customer">
|
||||
<!--
|
||||
Override the dynamic-map entity-mode
|
||||
|
@ -521,33 +557,29 @@ public interface Cuisine {
|
|||
<!-- other properties -->
|
||||
...
|
||||
</class>
|
||||
</hibernate-mapping>
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</hibernate-mapping></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section id="persistent-classes-entity-name-resolver" revision="0">
|
||||
<title>EntityNameResolvers</title>
|
||||
<section id="persistent-classes-entity-name-resolver">
|
||||
<title>EntityNameResolvers</title>
|
||||
|
||||
<para>The <interfacename>org.hibernate.EntityNameResolver</interfacename>
|
||||
interface is a contract for resolving the entity name of a given entity
|
||||
instance. The interface defines a single method
|
||||
<methodname>resolveEntityName</methodname> which is passed the entity
|
||||
instance and is expected to return the appropriate entity name (null is
|
||||
allowed and would indicate that the resolver does not know how to resolve
|
||||
the entity name of the given entity instance). Generally speaking, an
|
||||
<interfacename>org.hibernate.EntityNameResolver</interfacename> is going
|
||||
to be most useful in the case of dynamic models. One example might be
|
||||
using proxied interfaces as your domain model. The hibernate test suite
|
||||
has an example of this exact style of usage under the
|
||||
<package>org.hibernate.test.dynamicentity.tuplizer2</package>. Here is
|
||||
some of the code from that package for illustration.</para>
|
||||
<para>
|
||||
<interfacename>org.hibernate.EntityNameResolver</interfacename> is a contract for resolving the entity name
|
||||
of a given entity instance. The interface defines a single method <methodname>resolveEntityName</methodname>
|
||||
which is passed the entity instance and is expected to return the appropriate entity name (null is
|
||||
allowed and would indicate that the resolver does not know how to resolve the entity name of the given entity
|
||||
instance). Generally speaking, an <interfacename>org.hibernate.EntityNameResolver</interfacename> is going
|
||||
to be most useful in the case of dynamic models. One example might be using proxied interfaces as your
|
||||
domain model. The hibernate test suite has an example of this exact style of usage under the
|
||||
<package>org.hibernate.test.dynamicentity.tuplizer2</package>. Here is some of the code from that package
|
||||
for illustration.
|
||||
</para>
|
||||
|
||||
<programlisting role="JAVA">
|
||||
/**
|
||||
* A very trivial JDK Proxy InvocationHandler implementation where we proxy an interface as
|
||||
* the domain model and simply store persistent state in an internal Map. This is an extremely
|
||||
* trivial example meant only for illustration.
|
||||
<programlisting role="JAVA">/**
|
||||
* A very trivial JDK Proxy InvocationHandler implementation where we proxy an
|
||||
* interface as the domain model and simply store persistent state in an internal
|
||||
* Map. This is an extremely trivial example meant only for illustration.
|
||||
*/
|
||||
public final class DataProxyHandler implements InvocationHandler {
|
||||
private String entityName;
|
||||
|
@ -586,9 +618,6 @@ public final class DataProxyHandler implements InvocationHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ProxyHelper {
|
||||
public static String extractEntityName(Object object) {
|
||||
// Our custom java.lang.reflect.Proxy instances actually bundle
|
||||
|
@ -610,12 +639,14 @@ public class ProxyHelper {
|
|||
|
||||
/**
|
||||
* The EntityNameResolver implementation.
|
||||
* IMPL NOTE : An EntityNameResolver really defines a strategy for how entity names should be
|
||||
* resolved. Since this particular impl can handle resolution for all of our entities we want to
|
||||
* take advantage of the fact that SessionFactoryImpl keeps these in a Set so that we only ever
|
||||
* have one instance registered. Why? Well, when it comes time to resolve an entity name,
|
||||
* Hibernate must iterate over all the registered resolvers. So keeping that number down
|
||||
* helps that process be as speedy as possible. Hence the equals and hashCode impls
|
||||
*
|
||||
* IMPL NOTE : An EntityNameResolver really defines a strategy for how entity names
|
||||
* should be resolved. Since this particular impl can handle resolution for all of our
|
||||
* entities we want to take advantage of the fact that SessionFactoryImpl keeps these
|
||||
* in a Set so that we only ever have one instance registered. Why? Well, when it
|
||||
* comes time to resolve an entity name, Hibernate must iterate over all the registered
|
||||
* resolvers. So keeping that number down helps that process be as speedy as possible.
|
||||
* Hence the equals and hashCode implementations as is
|
||||
*/
|
||||
public class MyEntityNameResolver implements EntityNameResolver {
|
||||
public static final MyEntityNameResolver INSTANCE = new MyEntityNameResolver();
|
||||
|
@ -651,26 +682,26 @@ public class MyEntityTuplizer extends PojoEntityTuplizer {
|
|||
}
|
||||
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
</programlisting>
|
||||
|
||||
<para>In order to register an
|
||||
<interfacename>org.hibernate.EntityNameResolver</interfacename> users must
|
||||
either: <orderedlist>
|
||||
<listitem>
|
||||
<para>Implement a custom <link
|
||||
linkend="persistent-classes-tuplizers">Tuplizer</link>, implementing
|
||||
the <methodname>getEntityNameResolvers</methodname> method.</para>
|
||||
</listitem>
|
||||
<para>
|
||||
In order to register an <interfacename>org.hibernate.EntityNameResolver</interfacename> users must either:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Implement a custom tuplizer (see <xref linkend="persistent-classes-tuplizers"/>), implementing
|
||||
the <methodname>getEntityNameResolvers</methodname> method
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Register it with the <classname>org.hibernate.impl.SessionFactoryImpl</classname> (which is the
|
||||
implementation class for <interfacename>org.hibernate.SessionFactory</interfacename>) using the
|
||||
<methodname>registerEntityNameResolver</methodname> method.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<listitem>
|
||||
<para>Register it with the
|
||||
<classname>org.hibernate.impl.SessionFactoryImpl</classname> (which
|
||||
is the implementation class for
|
||||
<interfacename>org.hibernate.SessionFactory</interfacename>) using
|
||||
the <methodname>registerEntityNameResolver</methodname>
|
||||
method.</para>
|
||||
</listitem>
|
||||
</orderedlist></para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
|
Loading…
Reference in New Issue