|
|
|
@ -9,12 +9,27 @@
|
|
|
|
|
version="5.0"
|
|
|
|
|
xml:lang="en"
|
|
|
|
|
xmlns="http://docbook.org/ns/docbook"
|
|
|
|
|
>
|
|
|
|
|
<title>Identifiers</title>
|
|
|
|
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
|
|
|
|
|
|
|
|
|
<info>
|
|
|
|
|
<title>Identifiers</title>
|
|
|
|
|
<abstract>
|
|
|
|
|
<para>
|
|
|
|
|
This chapter discusses the characteristics of entity identifier attributes and modelling
|
|
|
|
|
them.
|
|
|
|
|
</para>
|
|
|
|
|
</abstract>
|
|
|
|
|
</info>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Identifiers model the primary key of an entity. They are used to uniquely identify each
|
|
|
|
|
specific entity. Every entity must define an identifier.
|
|
|
|
|
Identifiers model the primary key of an entity. They are used to uniquely identify each specific entity.
|
|
|
|
|
JPA defines the behavior of changing the value of the identifier attribute to be undefined; Hibernate simply
|
|
|
|
|
does not support that.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Every entity must define an identifier. For entity inheritance hierarchies, the identifier must be
|
|
|
|
|
defined just on the entity that is the root of the hierarchy.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<note>
|
|
|
|
@ -31,23 +46,401 @@
|
|
|
|
|
|
|
|
|
|
<!-- todo : be sure to discuss generators in simple, then reference from composite -->
|
|
|
|
|
|
|
|
|
|
<section>
|
|
|
|
|
<section xml:id="identifiers-simple">
|
|
|
|
|
<title>Simple identifiers</title>
|
|
|
|
|
<para></para>
|
|
|
|
|
<para>
|
|
|
|
|
Simple identifiers map to a single basic attribute, and are denoted using the
|
|
|
|
|
<interfacename>javax.persistence.Id</interfacename> annotation.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
According to JPA only the following types should be used as identifier attribute types:
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem><para>any Java primitive type</para></listitem>
|
|
|
|
|
<listitem><para>any primitive wrapper type</para></listitem>
|
|
|
|
|
<listitem><para>java.lang.String</para></listitem>
|
|
|
|
|
<listitem><para>java.util.Date (TemporalType#DATE)</para></listitem>
|
|
|
|
|
<listitem><para>java.sql.Date</para></listitem>
|
|
|
|
|
<listitem><para>java.math.BigDecimal</para></listitem>
|
|
|
|
|
<listitem><para>java.math.BigInteger</para></listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
Any types used for identifier attributes beyond this list will not be portable.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Values for simple identifiers can be assigned, as we have seen in the examples above. The expectation
|
|
|
|
|
for assigned identifier values is that the application assigns (sets them on the entity attribute) prior
|
|
|
|
|
to calling save/persist.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<example>
|
|
|
|
|
<title>Simple assigned identifier</title>
|
|
|
|
|
<programlisting role="JAVA"><xi:include href="extras/SimpleAssigned.java" parse="text" /></programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Values for simple identifiers can be generated. To denote that an identifier attribute is
|
|
|
|
|
generated, it is annotated with <interfacename>javax.persistence.GeneratedValue</interfacename>
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<example>
|
|
|
|
|
<title>Simple generated identifier</title>
|
|
|
|
|
<programlisting role="JAVA"><xi:include href="extras/SimpleGenerated.java" parse="text" /></programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Additionally to the type restriction list above, JPA
|
|
|
|
|
says that if using generated identifier values (see below) only integer types (short, int, long) will be
|
|
|
|
|
portably supported.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
The expectation for generated identifier values is that Hibernate will generate the value
|
|
|
|
|
when the save/persist occurs.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Identifier value generations strategies are discussed in detail in <xref linkend="identifiers-generators"/>.
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section>
|
|
|
|
|
<section xml:id="identifiers-composite">
|
|
|
|
|
<title>Composite identifiers</title>
|
|
|
|
|
<para></para>
|
|
|
|
|
|
|
|
|
|
<section>
|
|
|
|
|
<title>Composite identifiers - aggregated</title>
|
|
|
|
|
<para></para>
|
|
|
|
|
<para>
|
|
|
|
|
Composite identifiers correspond to one or more persistent attributes. A primary key class must be
|
|
|
|
|
defined to represent a composite primary key. Composite primary keys typically arise when mapping from
|
|
|
|
|
legacy databases when the database key is comprised of several columns. The EmbeddedId
|
|
|
|
|
or IdClass annotation is used to denote a composite primary key. See Sections 11.1.17 and
|
|
|
|
|
11.1.22.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<note>
|
|
|
|
|
<para>
|
|
|
|
|
The restriction that a composite identifier has to be represented by a "primary key class" is
|
|
|
|
|
a JPA restriction. Hibernate does allow composite identifiers to be defined without a
|
|
|
|
|
"primary key class", but use of that modeling technique is deprecated and not discussed here.
|
|
|
|
|
</para>
|
|
|
|
|
</note>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Here are the rules governing composite identifiers, as defined by the JPA specification.
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
The composite identifier must be represented by a "primary key class". The primary key class
|
|
|
|
|
may be defined using the <interfacename>javax.persistence.EmbeddedId</interfacename> annotation
|
|
|
|
|
(see <xref linkend="identifiers-composite-aggregated"/>) or defined using the
|
|
|
|
|
<interfacename>javax.persistence.IdClass</interfacename> annotation (see
|
|
|
|
|
<xref linkend="identifiers-composite-nonaggregated"/>).
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
The primary key class must be public and must have a public no-arg constructor.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
The primary key class must be serializable.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
The primary key class must define equals and hashCode methods, consistent with equality for
|
|
|
|
|
the underlying database types to which the key is mapped.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<section xml:id="identifiers-composite-aggregated">
|
|
|
|
|
<title>Composite identifiers - aggregated (EmbeddedId)</title>
|
|
|
|
|
<para>
|
|
|
|
|
<!-- todo : write -->
|
|
|
|
|
blah blah blah
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section>
|
|
|
|
|
<title>Composite identifiers - non-aggregated</title>
|
|
|
|
|
<para></para>
|
|
|
|
|
<section xml:id="identifiers-composite-nonaggregated">
|
|
|
|
|
<title>Composite identifiers - non-aggregated (IdClass)</title>
|
|
|
|
|
<para>
|
|
|
|
|
<!-- todo : write -->
|
|
|
|
|
blah blah blah
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section xml:id="identifiers-generators">
|
|
|
|
|
<title>Generated identifier values</title>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Hibernate supports identifier value generation across a number of different types. Remember
|
|
|
|
|
that JPA portably defines identifier value generation just for integer types.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Identifier value generation is indicates using the <interfacename>javax.persistence.GeneratedValue</interfacename>
|
|
|
|
|
annotation. The most important piece of information here is the specified
|
|
|
|
|
<interfacename>javax.persistence.GenerationType</interfacename> which indicates how values will be generated.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<note>
|
|
|
|
|
<para>
|
|
|
|
|
The discussions below assume that the application is using Hibernate's "new generator mappings" as
|
|
|
|
|
indicated by the <literal>hibernate.id.new_generator_mappings</literal> setting or
|
|
|
|
|
<methodname>MetadataBuilder.enableNewIdentifierGeneratorSupport</methodname> method during bootstrap.
|
|
|
|
|
For legacy reasons the default value for this setting is currently false, however we anticipate it
|
|
|
|
|
becoming true at some point. The rest of the discussion here assumes this setting is enabled (true).
|
|
|
|
|
</para>
|
|
|
|
|
</note>
|
|
|
|
|
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<title>GenerationTypes</title>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
<literal>AUTO</literal> (the default) - Indicates that the persistence provider (Hibernate) should
|
|
|
|
|
chose an appropriate generation strategy. See <xref linkend="identifiers-generators-auto"/>.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
<literal>IDENTITY</literal> - Indicates that database IDENTITY columns will be used for
|
|
|
|
|
primary key value generation. See <xref linkend="identifiers-generators-identity"/>.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
<literal>SEQUENCE</literal> - Indicates that database sequence should be used for obtaining
|
|
|
|
|
primary key values. See <xref linkend="identifiers-generators-sequence"/>.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
<literal>TABLE</literal> - Indicates that a database table should be used for obtaining
|
|
|
|
|
primary key values. See <xref linkend="identifiers-generators-table"/>.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
|
|
|
|
|
<section xml:id="identifiers-generators-auto">
|
|
|
|
|
<title>Interpreting AUTO</title>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
How a persistence provider interprets the AUTO generation type is left up to the provider. Hibernate
|
|
|
|
|
interprets it in the following order:
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
If the given name matches the name for a <interfacename>javax.persistence.SequenceGenerator</interfacename>
|
|
|
|
|
annotation -> <xref linkend="identifiers-generators-sequence"/>.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
If the given name matches the name for a <interfacename>javax.persistence.TableGenerator</interfacename>
|
|
|
|
|
annotation -> <xref linkend="identifiers-generators-table"/>.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
If the given name matches the name for a <interfacename>org.hibernate.annotations.GenericGenerator</interfacename>
|
|
|
|
|
annotation -> <xref linkend="identifiers-generators-generic"/>.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
The fallback is to consult with the pluggable <interfacename>org.hibernate.boot.model.IdGeneratorStrategyInterpreter</interfacename>
|
|
|
|
|
contract, which is covered in detail in the <citetitle>Hibernate Integrations Guide</citetitle>. The default
|
|
|
|
|
behavior is to look at the java type of the identifier attribute:
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
If it is UUID -> <xref linkend="identifiers-generators-uuid"/>
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
Otherwise -> <xref linkend="identifiers-generators-sequence"/>
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section xml:id="identifiers-generators-sequence">
|
|
|
|
|
<title>Using sequences</title>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
For implementing database sequence-based identifier value generation Hibernate makes use of its
|
|
|
|
|
<classname>org.hibernate.id.enhanced.SequenceStyleGenerator</classname> id generator. It is important
|
|
|
|
|
to note that SequenceStyleGenerator is capable of working against databases that do not support sequences
|
|
|
|
|
by switching to a table as the underlying backing. This gives Hibernate a huge degree of portability
|
|
|
|
|
across databases while still maintaining consistent id generation behavior (versus say choosing
|
|
|
|
|
between sequence and IDENTITY). This backing storage is completely transparent to the user.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
The preferred (and portable) way to configure this generator is using the JPA-defined
|
|
|
|
|
<interfacename>javax.persistence.SequenceGenerator</interfacename> annotation.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
The simplest form is to simply request sequence generation; Hibernate will use a single, implicitly-named
|
|
|
|
|
sequence (<literal>hibernate_sequence</literal>) for all such unnamed definitions.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<example>
|
|
|
|
|
<title>Unnamed sequence</title>
|
|
|
|
|
<programlisting role="JAVA"><xi:include href="extras/UnnamedSequence.java" parse="text" /></programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Or a specifically named sequence can be requested
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<example>
|
|
|
|
|
<title>Named sequence</title>
|
|
|
|
|
<programlisting role="JAVA"><xi:include href="extras/NamedSequence.java" parse="text" /></programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Use <interfacename>javax.persistence.SequenceGenerator</interfacename> to specify additional configuration.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<example>
|
|
|
|
|
<title>Configured sequence</title>
|
|
|
|
|
<programlisting role="JAVA"><xi:include href="extras/ConfiguredSequence.java" parse="text" /></programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
|
|
|
|
|
<!-- todo : SequenceStyleGenerator specific config (optimizer, forceTable, etc) -->
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section xml:id="identifiers-generators-identity">
|
|
|
|
|
<title>Using IDENTITY columns</title>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
For implementing identifier value generation based on IDENTITY columns, Hibernate makes use of its
|
|
|
|
|
<classname>org.hibernate.id.IdentityGenerator</classname> id generator which expects the identifier
|
|
|
|
|
to generated by INSERT into the table. IdentityGenerator understands 3 different ways that the
|
|
|
|
|
INSERT-generated value might be retrieved:
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
If Hibernate believes the JDBC environment supports <methodname>java.sql.Statement#getGeneratedKeys</methodname>,
|
|
|
|
|
then that approach will be used for extracting the IDENTITY generated keys.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
Otherwise, if <methodname>Dialect#supportsInsertSelectIdentity</methodname> reports
|
|
|
|
|
true, Hibernate will use the Dialect specific INSERT+SELECT statement syntax.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
Otherwise, Hibernate will expect that the database supports some form of asking
|
|
|
|
|
for the most recently inserted IDENTITY value via a separate SQL command as
|
|
|
|
|
indicated by <methodname>Dialect#getIdentitySelectString</methodname>
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
It is important to realize that this imposes a runtime behavior where the entity row *must* be
|
|
|
|
|
physically inserted prior to the identifier value being known. This can mess up extended persistence
|
|
|
|
|
contexts (conversations). Because of the runtime imposition/inconsistency Hibernate suggest other
|
|
|
|
|
forms of identifier value generation be used.
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section xml:id="identifiers-generators-table">
|
|
|
|
|
<title>Using identifier table</title>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
Hibernate achieves table-based identifier generation based on its
|
|
|
|
|
<interfacename>org.hibernate.id.enhanced.TableGenerator</interfacename> id generator which defines
|
|
|
|
|
a table capable of holding multiple named value segments for any number of entities.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<example>
|
|
|
|
|
<title>Table generator table structure</title>
|
|
|
|
|
<programlisting role="SQL"><xi:include href="extras/TableGenerator.sql" parse="text" /></programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
The basic idea is that a given table-generator table (<literal>hibernate_sequences</literal> for example)
|
|
|
|
|
can hold multiple segments of identifier generation values.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<example>
|
|
|
|
|
<title>Unnamed table generator</title>
|
|
|
|
|
<programlisting role="JAVA"><xi:include href="extras/UnnamedTable.java" parse="text" /></programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
If no table name is given Hibernate assumes an implicit name of <literal>hibernate_sequences</literal>.
|
|
|
|
|
Additionally, because no <methodname>javax.persistence.TableGenerator#pkColumnValue</methodname> is
|
|
|
|
|
specified, Hibernate will use the default segment (<literal>sequence_name='default'</literal>) from the
|
|
|
|
|
hibernate_sequences table.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<!-- todo : discuss setting org.hibernate.id.enhanced.TableGenerator specific settings -->
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section xml:id="identifiers-generators-uuid">
|
|
|
|
|
<title>Using UUID generation</title>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
As mentioned above, Hibernate supports UUID identifier value generation. This is supported through its
|
|
|
|
|
<classname>org.hibernate.id.UUIDGenerator</classname> id generator.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
UUIDGenerator supports pluggable strategies for exactly how the UUID is generated. These strategies
|
|
|
|
|
are defined by the <interfacename>org.hibernate.id.UUIDGenerationStrategy</interfacename> contract.
|
|
|
|
|
The default strategy is a version 4 (random) strategy according to IETF RFC 4122. Hibernate does ship
|
|
|
|
|
with an alternative strategy which is a RFC 4122 version 1 (time-based) strategy (using ip address
|
|
|
|
|
rather than mac address).
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<example>
|
|
|
|
|
<title>Implicitly using the random UUID strategy</title>
|
|
|
|
|
<programlisting role="JAVA"><xi:include href="extras/UUIDRandom.java" parse="text" /></programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
To specify an alternative generation strategy, we'd have to define some configuration via
|
|
|
|
|
@GenericGenerator. Here we choose the RFC 4122 version 1 compliant strategy named
|
|
|
|
|
<classname>org.hibernate.id.uuid.CustomVersionOneStrategy</classname>
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<example>
|
|
|
|
|
<title>Implicitly using the random UUID strategy</title>
|
|
|
|
|
<programlisting role="JAVA"><xi:include href="extras/UUIDCustomVersionOneStrategy.java" parse="text" /></programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section xml:id="identifiers-generators-generic">
|
|
|
|
|
<title>Using @GenericGenerator</title>
|
|
|
|
|
<para>
|
|
|
|
|
@GenericGenerator allows integration of any Hibernate <interfacename>org.hibernate.id.IdentifierGenerator</interfacename>
|
|
|
|
|
implementation, including any of the specific ones discussed here and any custom ones.
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<para>
|
|
|
|
|
For discussion of generated values for non-identifier attributes, see <xref linkend="generated"/>
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section xml:id="identifiers-derived">
|
|
|
|
|
<title>Derived Identifiers</title>
|
|
|
|
|
<para>
|
|
|
|
|
<!-- todo : write -->
|
|
|
|
|
Ugh...
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
</chapter>
|