[hibernate-commits] Hibernate SVN: r14075 - in core/trunk/documentation/manual/es-ES/src/main: docbook and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Oct 9 14:45:36 EDT 2007


Author: steve.ebersole at jboss.com
Date: 2007-10-09 14:45:36 -0400 (Tue, 09 Oct 2007)
New Revision: 14075

Added:
   core/trunk/documentation/manual/es-ES/src/main/docbook/Hibernate_Reference.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/architecture.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/association_mapping.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/basic_mapping.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/batch.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/best_practices.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/collection_mapping.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/component_mapping.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/configuration.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/events.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_mappings.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_parentchild.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_weblog.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/filters.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/inheritance_mapping.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/performance.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/persistent_classes.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/preface.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_criteria.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_hql.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_sql.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/quickstart.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/session_api.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/toolset_guide.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/transactions.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/tutorial.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/content/xml.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/AuthorWork.png
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/AuthorWork.zargo
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/CustomerOrderProduct.png
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/CustomerOrderProduct.zargo
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/EmployerEmployee.png
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/EmployerEmployee.zargo
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/full_cream.png
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/full_cream.svg
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/hibernate_logo_a.png
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/lite.png
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/lite.svg
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/overview.png
   core/trunk/documentation/manual/es-ES/src/main/docbook/images/overview.svg
   core/trunk/documentation/manual/es-ES/src/main/docbook/legal_notice.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/legal_notice2.xml
   core/trunk/documentation/manual/es-ES/src/main/docbook/translators.xml
Removed:
   core/trunk/documentation/manual/es-ES/src/main/docbook/master.xml
   core/trunk/documentation/manual/es-ES/src/main/resources/
Log:
new docbook layout (prep for translations migration to PO)

Added: core/trunk/documentation/manual/es-ES/src/main/docbook/Hibernate_Reference.xml
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/Hibernate_Reference.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/Hibernate_Reference.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,88 @@
+<?xml version='1.0' encoding="iso-8859-1"?>
+<!--
+  ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+  ~
+  ~ 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
+  ~ Lesser General Public License, v. 2.1. This program is distributed in the
+  ~ hope that it will be useful, but WITHOUT A WARRANTY; without even the implied
+  ~ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details. You should have received a
+  ~ copy of the GNU Lesser General Public License, v.2.1 along with this
+  ~ distribution; if not, write to the Free Software Foundation, Inc.,
+  ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  ~
+  ~ Red Hat Author(s): Steve Ebersole
+  -->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+        <!ENTITY versionNumber "3.3.0.alpha1">
+        <!ENTITY copyrightYear "2004">
+        <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
+]>
+
+<book>
+
+    <bookinfo>
+        <title>HIBERNATE - Persistencia Relacional para Java Idiom&#x00e1;tico</title>
+        <subtitle>Documentaci&#x00f3;n de Referencia de Hibernate</subtitle>
+        <releaseinfo>&versionNumber;</releaseinfo>
+        <productnumber>&versionNumber;</productnumber>
+        <issuenum>1</issuenum>
+        <mediaobject>
+            <imageobject role="fo">
+                <imagedata fileref="images/hibernate_logo_a.png" align="center" />
+            </imageobject>
+            <imageobject role="html">
+                <imagedata fileref="images/hibernate_logo_a.png" depth="3cm" />
+            </imageobject>
+        </mediaobject>
+        <copyright>
+            <year>&copyrightYear;</year>
+            <holder>&copyrightHolder;</holder>
+        </copyright>
+        <xi:include href="translators.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+        <xi:include href="legal_notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+        <xi:include href="legal_notice2.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    </bookinfo>
+
+    <toc/>
+
+    <xi:include href="content/preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+	<xi:include href="content/tutorial.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+	<xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+	<xi:include href="content/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+	<xi:include href="content/persistent_classes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/basic_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/collection_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/association_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/component_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/inheritance_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/session_api.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/transactions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/events.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/batch.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/query_hql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/query_criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/query_sql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/filters.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/xml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/performance.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/toolset_guide.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/example_parentchild.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/example_weblog.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/example_mappings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/best_practices.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/architecture.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/architecture.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/architecture.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/architecture.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,279 @@
+<chapter id="architecture">
+
+    <title>Arquitectura</title>
+
+    <sect1 id="architecture-overview" revision="1">
+        <title>Visi&#x00f3;n General</title>
+        
+        <para>
+            Una visi&#x00f3;n a (muy) alto nivel de la arquitectura de Hibernate:
+        </para>
+
+        <mediaobject>
+            <imageobject role="fo">
+                <imagedata fileref="../images/overview.svg" format="SVG" align="center"/>
+            </imageobject>
+            <imageobject role="html">
+                <imagedata fileref="../images/overview.gif" format="GIF" align="center"/>
+            </imageobject>
+        </mediaobject>
+
+        <para>
+            Este diagrama muestra a Hibernate usando la base de datos y los datos de
+            configuraci&#x00f3;n para proveer servicios de persistencia (y objetos
+            persistentes) a la aplicaci&#x00f3;n.
+        </para>
+
+        <para>
+            Nos gustar&#x00ed;a mostrar una vista m&#x00e1;s detallada de la arquitectura de tiempo
+            de ejecuci&#x00f3;n. Desafortunadamente, Hibernate es flexible y soporta diferentes
+            enfoques. Mostraremos los dos extremos. En la arquitectura "sencilla", es la
+            aplicaci&#x00f3;n la que provee su propias conexiones JDBC y gestiona sus propias
+            transacciones. Este enfoque usa un m&#x00ed;nimo subconjunto de la API de Hibernate:
+        </para>
+
+        <mediaobject>
+            <imageobject role="fo">
+                <imagedata fileref="../images/lite.svg" format="SVG" align="center"/>
+            </imageobject>
+            <imageobject role="html">
+                <imagedata fileref="../images/lite.gif" format="GIF" align="center"/>
+            </imageobject>
+        </mediaobject>
+
+        <para>
+            La arquitectura "full cream" abstrae a la aplicaci&#x00f3;n de las APIs
+            de JDBC/JTA y deja que Hibernate se encargue de los detalles.
+        </para>
+
+        <mediaobject>
+            <imageobject role="fo">
+                <imagedata fileref="../images/full_cream.svg" format="SVG" align="center"/>
+            </imageobject>
+            <imageobject role="html">
+                <imagedata fileref="../images/full_cream.gif" format="GIF" align="center"/>
+            </imageobject>
+        </mediaobject>
+
+        <para>
+            He aqu&#x00ed; algunas definiciones de los objetos en los diagramas:
+            <variablelist spacing="compact">
+                <varlistentry>
+                    <term>SessionFactory (<literal>org.hibernate.SessionFactory</literal>)</term>
+                    <listitem>
+                        <para>
+                            Cach&#x00e9; threadsafe (inmutable) de mapeos compilados para
+                            una sola base de datos. Es una f&#x00e1;brica de <literal>Session</literal>
+                            y un cliente de <literal>ConnectionProvider</literal>. Opcionalmente,
+                            puede mantener una cach&#x00e9; (de segundo nivel) de datos reusables
+                            entre transacciones, a un nivel de proceso o de cluster.
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>Session (<literal>org.hibernate.Session</literal>)</term>
+                    <listitem>
+                        <para>
+                            Objeto mono-hebra, de corta vida que representa una conversaci&#x00f3;n
+                            entre la aplicaci&#x00f3;n y el almacenamiento persistente. Envuelve una
+                            conexi&#x00f3;n JDBC. Es una f&#x00e1;brica de <literal>Transaction</literal>.
+                            Mantiene una cach&#x00e9; requerida (de primer nivel) de objetos persistentes,
+                            usada mientras se navega el grafo de objetos o se recuperen objetos por
+                            identificador.
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>Objetos y colecciones persistentes</term>
+                    <listitem>
+                        <para>
+                            Objetos de corta vida, mono-hebra conteniendo estado persistente y
+                            funci&#x00f3;nalidad de negocio. Estos pueden ser JavaBeans/POJOs
+                            (Plain Old Java Objects, o sea, cualquier objeto Java), la &#x00fa;nica
+                            cosa especial en ellos es que estan asociados actualmente con una
+                            (y s&#x00f3;lo una) <literal>Session</literal>. Tan pronto como la 
+                            <literal>Session</literal> sea cerrada, ser&#x00e1;n separados y
+                            estar&#x00e1;n libres para ser usados en cualquier capa de aplicaci&#x00f3;n.
+                            (por ejemplo, directamente como objetos de transferencia de datos hacia
+                            y desde la capa de presentaci&#x00f3;n).
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>Objetos y colecciones transitorios y separados</term>
+                    <listitem>
+                        <para>
+                            Instancias de clases persistentes que no estan acutualmente asociadas
+                            con una <literal>Session</literal>. Pueden haber sido instanciadas por
+                            la aplicaci&#x00f3;n y (a&#x00fa;n) no haber sido hechas persistentes,
+                            o pueden haber sido instanciadas por una <literal>Session</literal> cerrada.
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>Transaction (<literal>org.hibernate.Transaction</literal>)</term>
+                    <listitem>
+                        <para>
+                            (Opcional) Un objeto de corta vida, mono-hebra, usado por la aplicaci&#x00f3;n
+                            para especificar unidades at&#x00f3;micas de trabajo. Abstrae a la aplicaci&#x00f3;n
+                            de las subyacentes transacciones JDBC, JTA o CORBA. En algunos casos, una
+                            <literal>Session</literal> puede extenderse sobre varias <literal>Transaction</literal>s.
+                            Sin embargo, la demarcaci&#x00f3;n de la transacci&#x00f3;n, ya sea usando la API
+                            subyacente o <literal>Transaction</literal>, nunca es opcional!
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>ConnectionProvider (<literal>org.hibernate.connection.ConnectionProvider</literal>)</term>
+                    <listitem>
+                        <para>
+                            (Opcional) Una f&#x00e1;brica (y pool) de conexiones JDBC. Abstrae a la aplicaci&#x00f3;n
+                            del <literal>Datasource</literal> o <literal>DriverManager</literal> subyacente.
+                            No se expone a la aplicaci&#x00f3;n, pero puede ser extendido/implementado por
+                            el desarrollador.
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>TransactionFactory (<literal>org.hibernate.TransactionFactory</literal>)</term>
+                    <listitem>
+                        <para>
+                            (Opcional) Una f&#x00e1;brica de instancias de <literal>Transaction</literal>.
+                            No se expone a la aplicaci&#x00f3;n, pero puede ser extendido/implementado por
+                            el desarrollador.
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term><emphasis>Interfaces de Extensi&#x00f3;n</emphasis></term>
+                    <listitem>
+                        <para>
+                            Hibernate ofrece muchas interfaces de extensi&#x00f3;n opcional que puedes
+                            implementar para modificar a medida el comportamiento de tu capa de persistencia.
+                            Para m&#x00e1;s detalles, mira la documentaci&#x00f3;n de la API.
+                        </para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+        </para>
+
+        <para>
+            Dada una arquitectura "sencilla", la aplicaci&#x00f3;n pasa por alto las APIs
+            de <literal>Transaction</literal>/<literal>TransactionFactory</literal> y/o
+            <literal>ConnectionProvider</literal>, para hablar directamente a JTA o JDBC.
+        </para>
+    </sect1>
+
+    <sect1 id="architecture-states" revision="1">
+        <title>Estados de instancia</title>
+        <para>
+            Una instancia de una clase persistente puede estar en uno de tres estados
+            diferentes, definidos respecto de su <emphasis>contexto de persistencia</emphasis>.
+            El objeto <literal>Session</literal> de Hibernate es el contexto de persistencia:
+        </para>
+        
+       <variablelist spacing="compact">
+            <varlistentry>
+                <term>transitorio</term>
+                <listitem>
+                    <para>
+                        La instancia no est&#x00e1; y nunca estuvo asociada con
+                        un contexto de persistencia. No tiene identidad persistente
+                        (valor de clave primaria).
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>persistente</term>
+                <listitem>
+                    <para>
+                        La instancia est&#x00e1; actualmente asociada con un
+                        contexto de persistencia. Tiene una identidad persistente
+                        (valor de clave primaria) y, quiz&#x00e1;s, una fila
+                        correspondiente en la base de datos. Para un contexto de
+                        persistencia en particular, Hibernate <emphasis>garantiza</emphasis>
+                        que la identidad persistente es equivalente a la identidad
+                        Java (localizaci&#x00f3;n en memoria del objeto).
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>separado</term>
+                <listitem>
+                    <para>
+                        La instancia estuvo una vez asociada con un contexto
+                        de persistencia, pero ese contexto fue cerrado, o la
+                        instancia fue serializada a otro proceso. Tiene una
+                        identidad persistente y, quiz&#x00e1;s, una fila correspondiente
+                        en la base de datos. Para las instancias separadas,
+                        Hibernate no establece ninguna garant&#x00ed;a sobre
+                        la relaci&#x00f3;n entre identidad persistente e identidad Java.
+                    </para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </sect1>    
+
+    <sect1 id="architecture-jmx" revision="1">
+        <title>Integraci&#x00f3;n JMX</title>
+
+        <para>
+            JMX es el est&#x00e1;ndar J2EE para la gesti&#x00f3;n de componentes Java. Hibernate
+            puede ser gestionado por medio de un servicio est&#x00e1;ndar JMX.
+            Proveemos una implementaci&#x00f3;n de MBean en la distribuci&#x00f3;n,
+            <literal>org.hibernate.jmx.HibernateService</literal>.
+        </para>
+
+        <para>
+            Para ejemplo de c&#x00f3;mo desplegar Hibernate como un servicio JMX en un Servidor
+            de Aplicaciones JBoss, por favor, mira la Gu&#x00ed;a del Usuario de JBoss.
+            En JBoss AS, tienes adem&#x00e1;s estos beneficios si despliegas usando JMX:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    <emphasis>Gesti&#x00f3;n de Sesi&#x00f3;n:</emphasis> El ciclo de vida de la <literal>Session</literal>
+                    de Hibernate puede estar autom&#x00e1;ticamente ligado al &#x00e1;mbito de una transacci&#x00f3;n
+                    JTA. Esto significa que ya no tienes que abrir ni cerrar la <literal>Session</literal> manualmente,
+                    esto pasa a ser trabajo de un interceptor EJB de JBoss. Adem&#x00e1;s tampoco tienes
+                    que preocuparte m&#x00e1;s de la demarcaci&#x00f3;n de la transacci&#x00f3;n (a menos que
+                    que quieras escribir una capa de persitencia portable, por supuesto, usa la API de
+                    <literal>Transaction</literal> de Hibernate para esto). Para acceder a una
+                    <literal>Session</literal> llama al <literal>HibernateContext</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis>Despliegue de HAR:</emphasis> Usualmente despliegas el servicio JMX de Hibernate
+                    usando un descriptor de despliegue de servicio de JBoss (en un fichero EAR y/o SAR), que soporta
+                    todas las opciones de configuraci&#x00f3;n usuales de una <literal>SessionFactory</literal> de
+                    Hibernate. Sin embargo, todav&#x00ed;a tienes que nombrar todos tus ficheros de mapeo en el
+                    descriptor de despliegue. Si decides usar el depliegue de HAR opcional, JBoss detectar&#x00e1;
+                    autom&#x00e1;ticamente todos los ficheros de mapeo en tu fichero HAR.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Para m&#x00e1;s informaci&#x00f3;n sobre estas opciones, consulta la
+            Gu&#x00ed;a de Usuario del JBoss AS.
+        </para>
+
+        <para>
+            Otra funcionalidad disponible como un servicio JMX son las estad&#x00ed;sticas en
+            tiempo de ejecuci&#x00f3;n de Hibernate. Mira <xref linkend="configuration-optional-statistics"/>.
+        </para>
+    </sect1>
+
+    <sect1 id="architecture-jca" revision="1">
+        <title>Soporte JCA:</title>
+        <para>
+            Hiberate puede adem&#x00e1;s ser configurado como un conector JCA. Por favor mira el
+            sitio web para m&#x00e1;s detalles. Por favor ten en cuenta que el soporte de JCA
+            de Hibernate est&#x00e1; a&#x00fa;n considerado experimental.
+        </para>
+    </sect1>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/association_mapping.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/association_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/association_mapping.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/association_mapping.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,527 @@
+<chapter id="associations">
+
+    <title>Mapeos de Asociaci&#x00f3;n</title>
+
+    <sect1 id="assoc-intro" revision="1">
+        <title>Introducci&#x00f3;n</title>
+        
+        <para>
+            Los mapeos de asociaci&#x00f3;n son frecuentemente las cosas mas dif&#x00ed;ciles
+            de hacer correctamente. En esta secci&#x00f3;n iremos a trav&#x00e9;s de los casos
+            can&#x00f3;nicos uno a uno, comenzando con los mapeos unidireccionales, y considerando
+            luego los casos bidireccionales. Usaremos <literal>Person</literal> y <literal>Address</literal>
+            en todos los ejemplos.
+        </para>
+        
+        <para>
+                Clasificaremos las asociaciones por cuanto mapeen o no a una tabla
+                de uni&#x00f3;n interviniente, y por su multiplicidad.
+        </para>
+        
+        <para>
+                Las claves for&#x00e1;neas que aceptan valores nulos (en adelante, nullables)
+                no son consideradas una buena pr&#x00e1;ctica en el modelado tradicional de datos,
+                as&#x00ed; que todos nuestros ejemplos usan claves for&#x00e1;neas no nullables.
+                Esto no es un requerimiento de Hibernate, y todos los mapeos funcionar&#x00e1;n
+                si quitas las restricciones de nulabilidad.
+        </para>
+        
+    </sect1>
+
+    <sect1 id="assoc-unidirectional" revision="1">
+        <title>Asociaciones Unidireccionales</title>
+        
+        <sect2 id="assoc-unidirectional-m21">
+        <title>muchos a uno</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n unidireccional muchos-a-uno</emphasis> es el tipo
+            m&#x00e1;s com&#x00fa;n de asociaciones unidireccionales.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <many-to-one name="address" 
+        column="addressId"
+        not-null="true"/>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+
+        <sect2 id="assoc-unidirectional-121">
+        <title>uno a uno</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n unidireccional uno-a-uno en una clave primaria</emphasis>
+            es casi id&#x00e9;ntica. La &#x00fa;nica diferencia es la restricci&#x00f3;n de unicidad
+            de la columna.
+        </para>
+        
+       <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <many-to-one name="address" 
+        column="addressId" 
+        unique="true"
+        not-null="true"/>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        <para>
+            Usualmente, una <emphasis>asociaci&#x00f3;n unidireccional uno-a-uno en una
+            clave primaria</emphasis> usa un generador de id especial. (Observa que hemos
+            invertido el sentido de la asociaci&#x00f3;n en este ejemplo).
+        </para>
+        
+       <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+</class>
+
+<class name="Address">
+    <id name="id" column="personId">
+        <generator class="foreign">
+            <param name="property">person</param>
+        </generator>
+    </id>
+    <one-to-one name="person" constrained="true"/>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+        
+        <sect2 id="assoc-unidirectional-12m">
+        <title>uno a muchos</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n unidireccional uno-a-muchos en una clave for&#x00e1;nea</emphasis>
+            es un caso muy inusual, y realmente no est&#x00e1; recomendada.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <set name="addresses">
+        <key column="personId" 
+            not-null="true"/>
+        <one-to-many class="Address"/>
+    </set>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( addressId bigint not null primary key, personId bigint not null )
+        ]]></programlisting>
+        
+        <para>
+            Creemos que es mejor usar una tabla de uni&#x00f3;n para este tipo de asociaci&#x00f3;n.
+        </para>
+        
+        </sect2>
+    
+    </sect1>
+
+    <sect1 id="assoc-unidirectional-join" revision="1">
+        <title>Asociaciones unidireccionales con tablas de uni&#x00f3;n</title>
+        
+        <sect2 id="assoc-unidirectional-join-12m">
+        <title>uno a muchos</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n unidireccional uno-a-muchos en una tabla de uni&#x00f3;n</emphasis>
+            es m&#x00e1;s preferible. Observa que especificando <literal>unique="true"</literal>, hemos
+            cambiado la multiplicidad de muchos-a-muchos a uno-a-muchos.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <set name="addresses" table="PersonAddress">
+        <key column="personId"/>
+        <many-to-many column="addressId"
+            unique="true"
+            class="Address"/>
+    </set>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+
+        <sect2 id="assoc-unidirectional-join-m21">
+        <title>muchos a uno</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n unidireccional muchos-a-uno en una tabla de uni&#x00f3;n</emphasis>
+            es bastante com&#x00fa;n cuando la asociaci&#x00f3;n es opcional.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <join table="PersonAddress" 
+        optional="true">
+        <key column="personId" unique="true"/>
+        <many-to-one name="address"
+            column="addressId" 
+            not-null="true"/>
+    </join>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+
+        <sect2 id="assoc-unidirectional-join-121">
+        <title>uno a uno</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n unidireccional uno-a-uno en una tabla de uni&#x00f3;n</emphasis>
+            es inusual en extremo, pero posible.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <join table="PersonAddress" 
+        optional="true">
+        <key column="personId" 
+            unique="true"/>
+        <many-to-one name="address"
+            column="addressId" 
+            not-null="true"
+            unique="true"/>
+    </join>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+
+        <sect2 id="assoc-unidirectional-join-m2m">
+        <title>muchos a muchos</title>
+        
+        <para>
+            Finalmente, tenemos una <emphasis>asociaci&#x00f3;n unidireccional muchos-a-muchos</emphasis>
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <set name="addresses" table="PersonAddress">
+        <key column="personId"/>
+        <many-to-many column="addressId"
+            class="Address"/>
+    </set>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="assoc-bidirectional" revision="1">
+        <title>Asociaciones Bidireccionales</title>
+        
+        <sect2 id="assoc-bidirectional-m21">
+        <title>uno a muchos / muchos a uno</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n bidireccional muchos-a-uno</emphasis> es
+            el tipo m&#x00e1;s com&#x00fa;n de asociaci&#x00f3;n. (Esta es la relaci&#x00f3;n
+            est&#x00e1;ndar padre/hijo.)
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <many-to-one name="address" 
+        column="addressId"
+        not-null="true"/>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+    <set name="people" inverse="true">
+        <key column="addressId"/>
+        <one-to-many class="Person"/>
+    </set>
+</class>]]></programlisting>
+
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+        
+        <sect2 id="assoc-bidirectional-121">
+        <title>uno a uno</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n bidireccional uno-a-uno en una clave for&#x00e1;nea</emphasis>
+            es bastante com&#x00fa;n.
+        </para>
+        
+       <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <many-to-one name="address" 
+        column="addressId" 
+        unique="true"
+        not-null="true"/>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+   <one-to-one name="person" 
+        property-ref="address"/>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n bidireccional uno-a-uno en una clave primaria</emphasis>
+            usa el generador de id especial.
+        </para>
+        
+       <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <one-to-one name="address"/>
+</class>
+
+<class name="Address">
+    <id name="id" column="personId">
+        <generator class="foreign">
+            <param name="property">person</param>
+        </generator>
+    </id>
+    <one-to-one name="person" 
+        constrained="true"/>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table Address ( personId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+        
+    </sect1>
+
+    <sect1 id="assoc-bidirectional-join" revision="1">
+        <title>Asociaciones bidireccionales con tablas de uni&#x00f3;n</title>
+        
+        <sect2 id="assoc-bidirectional-join-12m">
+        <title>uno a muchos / muchos a uno</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n bidireccional uno-a-muchos en una tabla de uni&#x00f3;n</emphasis>.
+            Observa que el <literal>inverse="true"</literal> puede ir a cualquier lado de la asociaci&#x00f3;n,
+            en la colecci&#x00f3;n, o en la uni&#x00f3;n.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <set name="addresses" 
+        table="PersonAddress">
+        <key column="personId"/>
+        <many-to-many column="addressId"
+            unique="true"
+            class="Address"/>
+    </set>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+    <join table="PersonAddress" 
+        inverse="true" 
+        optional="true">
+        <key column="addressId"/>
+        <many-to-one name="person"
+            column="personId"
+            not-null="true"/>
+    </join>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null primary key )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+
+         <sect2 id="assoc-bidirectional-join-121">
+        <title>uno a uno</title>
+        
+        <para>
+            Una <emphasis>asociaci&#x00f3;n bidireccional uno-a-uno en una tabla de uni&#x00f3;n</emphasis>
+            es inusual en extremo, pero posible.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <join table="PersonAddress" 
+        optional="true">
+        <key column="personId" 
+            unique="true"/>
+        <many-to-one name="address"
+            column="addressId" 
+            not-null="true"
+            unique="true"/>
+    </join>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+    <join table="PersonAddress" 
+        optional="true"
+        inverse="true">
+        <key column="addressId" 
+            unique="true"/>
+        <many-to-one name="address"
+            column="personId" 
+            not-null="true"
+            unique="true"/>
+    </join>
+</class>]]></programlisting>
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+
+        </sect2>
+        
+        <sect2 id="assoc-bidirectional-join-m2m">
+        <title>muchos a muchos</title>
+        
+        <para>
+            Finalmente, tenemos una <emphasis>asociaci&#x00f3;n bidireccional muchos-a-muchos</emphasis>.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id" column="personId">
+        <generator class="native"/>
+    </id>
+    <set name="addresses">
+        <key column="personId"/>
+        <many-to-many column="addressId"
+            class="Address"/>
+    </set>
+</class>
+
+<class name="Address">
+    <id name="id" column="addressId">
+        <generator class="native"/>
+    </id>
+    <set name="people" inverse="true">
+        <key column="addressId"/>
+        <many-to-many column="personId"
+            class="Person"/>
+    </set>
+</class>]]></programlisting>
+
+        <programlisting><![CDATA[
+create table Person ( personId bigint not null primary key )
+create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )
+create table Address ( addressId bigint not null primary key )
+        ]]></programlisting>
+        
+        </sect2>
+        
+    </sect1>
+
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/basic_mapping.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/basic_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/basic_mapping.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/basic_mapping.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,3222 @@
+<chapter id="mapping">
+    <title>Mapeo O/R B&#x00e1;sico</title>
+
+    <sect1 id="mapping-declaration" revision="1">
+        <title>Declaraci&#x00f3;n de mapeo</title>
+
+        <para>
+            Los mapeos objeto/relacional se definen usualmente en un documento XML.
+            El documento de mapeo est&#x00e1; dise&#x00f1;ado para ser le&#x00ed;ble y 
+            editable a mano. El lenguaje de mapeo es Java-c&#x00e9;ntrico, o sea que los
+            mapeos se construyen alrededor de declaraciones de clases persistentes,
+            no declaraciones de tablas.
+        </para>
+        
+        <para>
+            Observa que, incluso aunque muchos usuarios de Hibernate eligen escribir el
+            XML a mano, existe una cantidad de herramientas para generar el documento de
+            mapeo, incluyendo XDoclet, Middlegen y AndroMDA.
+        </para>
+
+        <para>
+            Comencemos por un mapeo de ejemplo:
+        </para>
+
+        <programlisting id="mapping-declaration-ex1" revision="1"><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+        <class name="Cat" 
+            table="cats"
+            discriminator-value="C">
+                
+                <id name="id">
+                        <generator class="native"/>
+                </id>
+
+                <discriminator column="subclass" 
+                     type="character"/>
+
+                <property name="weight"/>
+
+                <property name="birthdate"
+                    type="date" 
+                    not-null="true" 
+                    update="false"/>
+
+                <property name="color"
+                    type="eg.types.ColorUserType"
+                    not-null="true"
+                    update="false"/>
+
+                <property name="sex"
+                    not-null="true" 
+                    update="false"/>
+
+                <property name="litterId"
+                    column="litterId"
+                    update="false"/>
+
+                <many-to-one name="mother"
+                    column="mother_id"
+                    update="false"/>
+
+                <set name="kittens"
+                    inverse="true"
+                    order-by="litter_id">
+                        <key column="mother_id"/>
+                        <one-to-many class="Cat"/>
+                </set>
+
+                <subclass name="DomesticCat"
+                    discriminator-value="D">
+
+                        <property name="name" 
+                            type="string"/>
+
+                </subclass>
+
+        </class>
+
+        <class name="Dog">
+                <!-- mapping for Dog could go here -->
+        </class>
+
+</hibernate-mapping>]]></programlisting>
+
+        <para>
+             Discutiremos ahora el contenido del documento de mapeo. Describiremos s&#x00f3;lo los
+             elementos y atributos que son usados por Hibernate en tiempo de ejecuci&#x00f3;n. El
+             documento de mapeo contiene adem&#x00e1;s algunos atributos y elementos extra opcionales
+             que afectan los esquemas de base de datos exportados por la herramienta de exportaci&#x00f3;n
+             de esquemas. (Por ejemplo, el atributo <literal>not-null</literal>.)
+        </para>
+
+
+
+        <sect2 id="mapping-declaration-doctype" revision="2">
+            <title>Doctype</title>
+
+            <para>
+                Todos los mapeos XML deben declarar el doctype mostrado. El DTD actual puede
+                ser encontrado en el URL mencionado arriba, en el directorio
+                <literal>hibernate-x.x.x/src/org/hibernate</literal>, o en <literal>hibernate3.jar</literal>.
+                Hibernate siempre buscar&#x00e1; el DTD primero en el classpath. Si experimentas
+                b&#x00fa;squedas del DTD usando una conexi&#x00f3;n de Internet, chequea tu declaraci&#x00f3;n
+                de DTD contra la contenida en el classpath.
+            </para>
+        </sect2>
+
+        <sect2 id="mapping-declaration-mapping" revision="3">
+            <title>hibernate-mapping</title>
+
+            <para>
+                Este elemento tiene muchos atributos opcionales. Los atributos <literal>schema</literal>
+                y <literal>catalog</literal> especifican que las tablas a las que se refiere en el mapeo
+                pertenecen al esquema y/o cat&#x00e1;logo mencionado(s). De especificarse, los nombres de
+                tablas ser&#x00e1;n cualificados por el nombre de esquema y cat&#x00e1;logo dados.
+                De omitirse, los nombres de tablas no ser&#x00e1;n cualificados. El atributo
+                <literal>default-cascade</literal> especifica qu&#x00e9; estilo de cascada debe asumirse
+                para las propiedades y colecciones que no especifican un atributo <literal>cascade</literal>.
+                El atributo <literal>auto-import</literal> nos permite usar nombres de clase sin cualificar
+                en el lenguaje de consulta, por defecto.
+            </para>
+ 
+             <programlistingco>
+                 <areaspec>
+                     <area id="hm1" coords="2 55"/>
+                     <area id="hm2" coords="3 55"/>
+                     <area id="hm3" coords="4 55"/>
+                     <area id="hm4" coords="5 55"/>
+                     <area id="hm5" coords="6 55"/>
+                     <area id="hm6" coords="7 55"/>
+                     <area id="hm7" coords="8 55"/>
+                 </areaspec>
+                 <programlisting><![CDATA[<hibernate-mapping
+         schema="schemaName"
+         catalog="catalogName"
+         default-cascade="cascade_style"
+         default-access="field|property|ClassName"
+         default-lazy="true|false"
+         auto-import="true|false"
+         package="package.name"
+ />]]></programlisting>
+                 <calloutlist>
+                     <callout arearefs="hm1">
+                         <para>
+                             <literal>schema</literal> (opcional): El nombre de un esquema de la base de datos.
+                         </para>
+                     </callout>
+                     <callout arearefs="hm2">
+                         <para>
+                             <literal>catalog</literal> (opcional): El nombre de un cat&#x00e1;logo de la base de datos.
+                         </para>
+                     </callout>
+                     <callout arearefs="hm3">
+                         <para>
+                             <literal>default-cascade</literal> (opcional - por defecto a <literal>none</literal>): 
+                             Un estilo de cascada por defecto.
+                         </para>
+                     </callout>
+                     <callout arearefs="hm4">
+                         <para>
+                             <literal>default-access</literal> (opcional - por defecto a <literal>property</literal>):
+                             La estrategia que Hibernate debe usar para acceder a todas las propiedades.
+                             Puede ser una implementaci&#x00f3;n personalizada de <literal>PropertyAccessor</literal>.
+                         </para>
+                     </callout>
+                     <callout arearefs="hm5">
+                         <para>
+                             <literal>default-lazy</literal> (opcional - por defecto a <literal>true</literal>):
+                             El valor por defecto para los atributos <literal>lazy</literal> de mapeos de clase
+                             y colleci&#x00f3;n no especificados.
+                         </para>
+                     </callout>
+                     <callout arearefs="hm6">
+                         <para>
+                             <literal>auto-import</literal> (opcional - por defecto a <literal>true</literal>):
+                             Especifica si podemos usar nombres de clases no cualificados (de clases en este mapeo)
+                             en el lenguaje de consulta.
+                         </para>
+                     </callout>
+                     <callout arearefs="hm7">
+                         <para>
+                             <literal>package</literal> (opcional): Especifica un prefijo de paquete a asumir
+                             para los nombres no cualificados de clase en el documento de mapeo.
+                         </para>
+                     </callout>
+                 </calloutlist>
+             </programlistingco>
+             
+             <para>
+                 Si tienes dos clases persistentes con el mismo nombre (sin cualificar), debes establecer
+                 <literal>auto-import="false"</literal>. Hibernate lanzar&#x00e1; una excepci&#x00f3;n si
+                 intentas asignar dos clases al mismo nombre "importado".
+             </para>
+
+             <para>
+                 Observa que el elemento <literal>hibernate-mapping</literal> te permite anidar
+                 muchos mapeos <literal>&lt;class&gt;</literal> persistentes, como se muestra arriba.
+                 Sin embargo, es una buena pr&#x00e1;ctica (y se espera de algunas herramientas) mapear
+                 s&#x00f3;lo a una sola clase persistente (o a una sola jerarqu&#x00ed;a de clases) en
+                 un fichero de mapeo y nombrarlo despu&#x00e9;s de la superclase persistente;
+                 por ejemplo, <literal>Cat.hbm.xml</literal>, <literal>Dog.hbm.xml</literal>,
+                 o, si se usa herencia, <literal>Animal.hbm.xml</literal>.
+             </para>
+ 
+        </sect2>
+
+        <sect2 id="mapping-declaration-class" revision="3">
+            <title>class</title>
+
+            <para>
+                Puedes declarar una clase persistente usando el elemento <literal>class</literal>:
+            </para>
+            
+            <programlistingco>
+                <areaspec>
+                    <area id="class1" coords="2 55"/>
+                    <area id="class2" coords="3 55" />
+                    <area id="class3" coords="4 55"/>
+                    <area id="class4" coords="5 55" />
+                    <area id="class5" coords="6 55"/>
+                    <area id="class6" coords="7 55" />
+                    <area id="class7" coords="8 55"/>
+                    <area id="class8" coords="9 55" />
+                    <area id="class9" coords="10 55" />
+                    <area id="class10" coords="11 55"/>
+                    <area id="class11" coords="12 55"/>
+                    <area id="class12" coords="13 55"/>
+                    <area id="class13" coords="14 55"/>
+                    <area id="class14" coords="15 55"/>
+                    <area id="class15" coords="16 55"/>
+                    <area id="class16" coords="17 55"/>
+                    <area id="class17" coords="18 55"/>
+                    <area id="class18" coords="19 55"/>
+                    <area id="class19" coords="20 55"/>
+                    <area id="class20" coords="21 55"/>
+                    <area id="class21" coords="22 55"/>
+                </areaspec>
+                <programlisting><![CDATA[<class
+        name="ClassName"
+        table="tableName"
+        discriminator-value="discriminator_value"
+        mutable="true|false"
+        schema="owner"
+        catalog="catalog"
+        proxy="ProxyInterface"
+        dynamic-update="true|false"
+        dynamic-insert="true|false"
+        select-before-update="true|false"
+        polymorphism="implicit|explicit"
+        where="arbitrary sql where condition"
+        persister="PersisterClass"
+        batch-size="N"
+        optimistic-lock="none|version|dirty|all"
+        lazy="true|false"
+        entity-name="EntityName"
+        check="arbitrary sql check condition"
+        rowid="rowid"
+        subselect="SQL expression"
+        abstract="true|false"
+        node="element-name"
+/>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="class1">
+                        <para>
+                            <literal>name</literal> (opcional): El nombre completamente cualificado de la clase
+                            Java persistente (o interface). Si este atributo es omitido, se asume que el mapeo
+                            es para una entidad non-POJO.
+                        </para>
+                    </callout>
+                    <callout arearefs="class2">
+                        <para>
+                            <literal>table</literal> (opcional - por defecto al nombre no cualificado de la clase):
+                            El nombre de su tabla en base de datos.
+                        </para>
+                    </callout>
+                    <callout arearefs="class3">
+                        <para>
+                            <literal>discriminator-value</literal> (opcional - por defecto al nombre de la clase):
+                            Un valor que distingue subclases individuales, usado para el comportamiento
+                            polim&#x00f3;rfico. Los valores aceptables incluyen <literal>null</literal>
+                            y <literal>not null</literal>.
+                        </para>
+                    </callout>
+                    <callout arearefs="class4">
+                        <para>
+                            <literal>mutable</literal> (opcional, por defecto a <literal>true</literal>):
+                            Especifica que las instancias de la clase (no) son mutables.
+                        </para>
+                    </callout>    
+                    <callout arearefs="class5">
+                        <para>
+                            <literal>schema</literal> (opcional): Sobreescribe el nombre de esquema especificado
+                            por el elemento ra&#x00ed;z <literal>&lt;hibernate-mapping&gt;</literal>.
+                        </para>
+                    </callout>                
+                    <callout arearefs="class6">
+                        <para>
+                            <literal>catalog</literal> (opcional): Sobreescribe el nombre de cat&#x00e1;logo
+                            especificado por el elemento ra&#x00ed;z <literal>&lt;hibernate-mapping&gt;</literal>.
+                        </para>
+                    </callout>                
+                    <callout arearefs="class7">
+                        <para>
+                            <literal>proxy</literal> (opcional): Especifica una interface a usar para proxies
+                            de inicializaci&#x00f3;n perezosa. Puedes especificar el nombre mismo de la clase.
+                        </para>
+                    </callout>    
+                    <callout arearefs="class8">
+                        <para>
+                            <literal>dynamic-update</literal> (opcional, por defecto a <literal>false</literal>): 
+                            Especifica que el SQL <literal>UPDATE</literal> debe ser generado en tiempo de
+                            ejecuci&#x00f3;n y contener solamente aquellas columnas cuyo valor haya cambiado.
+                        </para>
+                    </callout>    
+                    <callout arearefs="class9">
+                        <para>
+                            <literal>dynamic-insert</literal> (opcional, por defecto a <literal>false</literal>): 
+                            Especifica que el SQL <literal>INSERT</literal> debe ser generado en tiempo de
+                            ejecuci&#x00f3;n y contener solamente aquellas columnas cuyo valores no son nulos.
+                        </para>
+                    </callout>    
+                    <callout arearefs="class10">
+                        <para>
+                            <literal>select-before-update</literal> (opcional, por defecto a <literal>false</literal>): 
+                            Especifica que Hibernate <emphasis>nunca</emphasis> debe realizar un SQL <literal>UPDATE</literal> 
+                            a menos que se tenga certeza que un objeto haya sido modificado realmente.
+                            En ciertos casos, (realmente, s&#x00f3;lo cuando un objeto transitorio ha sido asociado
+                            con una sesi&#x00f3;n nueva usando <literal>update()</literal>), esto significa que Hibernate
+                            realizar&#x00e1; una SQL <literal>SELECT</literal> extra para determinar si un
+                            <literal>UPDATE</literal> es realmente requerido.
+                        </para>
+                    </callout>    
+                    <callout arearefs="class11">
+                        <para>
+                            <literal>polymorphism</literal> (opcional, por defecto a <literal>implicit</literal>): 
+                            Determina si se usa polimorfismo de consulta impl&#x00ed;cito o expl&#x00ed;cito.
+                        </para>
+                    </callout>    
+                    <callout arearefs="class12">
+                        <para>
+                            <literal>where</literal> (opcional) especifica una condici&#x00f3;n SQL <literal>WHERE</literal>
+                            arbitraria paraa ser usada al recuperar objetos de esta clase.
+                        </para>
+                    </callout>                 
+                    <callout arearefs="class13">
+                        <para>
+                            <literal>persister</literal> (opcional): Especifica un <literal>ClassPersister</literal>
+                            personalizado.
+                        </para>
+                    </callout>                 
+                    <callout arearefs="class14">
+                        <para>
+                            <literal>batch-size</literal> (opcional, por defecto a <literal>1</literal>)
+                            especifica un "tama&#x00f1;o de lote" para traer instancias de esta clase por
+                            identificador.
+                        </para>
+                    </callout>                 
+                   <callout arearefs="class15">
+                        <para>
+                            <literal>optimistic-lock</literal> (opcional, por defecto a <literal>version</literal>):
+                            Determina la estrategia optimista de bloqueo.
+                        </para>
+                    </callout>    
+                    <callout arearefs="class16">
+                        <para>
+                            <literal>lazy</literal> (opcional):
+                            La recuperaci&#x00f3;n perezosa puede ser deshabilitada por completo estableciendo
+                            <literal>lazy="false"</literal>.
+                        </para>
+                    </callout>    
+                    <callout arearefs="class17">
+                        <para>
+                            <literal>entity-name</literal> (opcional): Hibernate3 permite que una clase sea
+                            mapeada varias veces (potencialmente a tablas diferentes), y permite que los mapeos
+                            de entidad sean representados por Maps o XML al nivel de Java. En estos casos,
+                            debes proveer un nombre expl&#x00ed;cito arbitrario para la entidad.
+                            Para m&#x00e1;s informaci&#x00f3;n, mira
+                            <xref linkend="persistent-classes-dynamicmodels"/> y <xref linkend="xml"/>.
+                        </para>
+                    </callout>
+                    <callout arearefs="class18">
+                        <para>
+                            <literal>check</literal> (opcional): Una expresi&#x00f3;n SQL usada para generar
+                            una restricci&#x00f3;n <emphasis>check</emphasis> multi-fila para la generaci&#x00f3;n
+                            autom&#x00e1;tica de esquema.
+                        </para>
+                    </callout>
+                    <callout arearefs="class19">
+                        <para>
+                            <literal>rowid</literal> (opcional): Hibernate puede usar los llamados ROWIDs en las
+                            bases de datos que los soporten. Por ejemplo, en Oracle, Hibernate puede usar la columna
+                            extra <literal>rowid</literal> para actualizaciones r&#x00e1;pidas si estableces esta
+                            opci&#x00f3;n a <literal>rowid</literal>. Un ROWID es un detalle de implementaci&#x00f3;n
+                            y representa la posici&#x00f3;n f&#x00ed;sica de la tupla almacenada.
+                        </para>
+                    </callout>
+                    <callout arearefs="class20">
+                        <para>
+                            <literal>subselect</literal> (opcional): Mapea una entidad inmutable y de s&#x00f3;lo
+                            lectura a una subselect de base de datos. Es &#x00fa;til si quieres tener una vista
+                            en vez de una tabla base, pero no tienes vistas. Mira debajo para m&#x00e1;s informaci&#x00f3;n.
+                        </para>
+                    </callout>
+                    <callout arearefs="class21">
+                        <para>
+                            <literal>abstract</literal> (opcional): Usado para marcar superclases abstractas en
+                            jerarqu&#x00ed;as <literal>&lt;union-subclass&gt;</literal>.
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+           
+            <para>
+                Es perfectamente aceptable que la clase persistente mencionada sea una interface.
+                Entonces declarar&#x00ed;as clases que implementan esa interface usando el elemento
+                <literal>&lt;subclass&gt;</literal>. Puedes persistir cualquier clase interna
+                <emphasis>est&#x00e1;tica</emphasis>. Debes especificar el nombre de la clase usando la forma
+                est&#x00e1;ndar. Por ejemplo, <literal>eg.Foo$Bar</literal>.
+            </para>
+
+            <para>
+                Las clases inmutables, <literal>mutable="false"</literal>, no pueden ser actualizadas o
+                borradas por la aplicaci&#x00f3;n. Esto permite a Hibernate hacer ciertas optimizaciones
+                menores de rendimiento.
+            </para>
+            
+            <para>
+                El atributo opcional <literal>proxy</literal> habilita la inicializaci&#x00f3;n postergada
+                de instancias persistentes de la clase. Hibernate inicialmente retornar&#x00e1; proxies
+                CGLIB que implementan la interface mencionada. El objeto persistente real ser&#x00e1;
+                cargado cuando se invoque un m&#x00e9;todo del proxy. Mira "Proxies para Inicializaci&#x00f3;n
+                Postergada" debajo.
+            </para>
+            
+            <para>
+                Por polimorfismo <emphasis>impl&#x00ed;cito</emphasis> se entiende que las instancias de la clase
+                ser&#x00e1;n devueltas por una consulta que mencione cualquier superclase, o interface implementada,
+                o la clase misma; y que las instancias de cualquier subclase de la clase ser&#x00e1;n devueltas
+                por una clase que mencione a la clase en s&#x00ed;.
+                Por polimorfismo <emphasis>expl&#x00ed;cito</emphasis> se entiende que instancias de la clase
+                ser&#x00e1;n devueltas s&#x00f3;lo por consultas que mencionen expl&#x00ed;citamente la clase;
+                y que las consultas que mencionen la clase devolver&#x00e1;n s&#x00f3;lo instancias de subclases
+                mapeadas dentro de esta declaraci&#x00f3;n <literal>&lt;class&gt;</literal> como una
+                <literal>&lt;subclass&gt;</literal> o <literal>&lt;joined-subclass&gt;</literal>.
+                Para la mayor&#x00ed;a de los prop&#x00f3;sitos el defecto,
+                <literal>polymorphism="implicit"</literal>, resulta apropiado.
+                El polimorfismo expl&#x00ed;cito es &#x00fa;til cuando dos clases diferentes est&#x00e1;n
+                mapeadas a la misma tabla (esto permite tener una clase "liviana" que contenga un subconjunto
+                de columnas de la tabla).
+            </para>
+            
+            <para>
+                El atributo <literal>persister</literal> te permite personalizar la estrategia de persistencia
+                para la clase. Puedes, por ejemplo, especificar tu propia subclase de
+                <literal>org.hibernate.persister.EntityPersister</literal> o incluso puedes proveer una implementaci&#x00f3;n
+                completamente nueva de la interface <literal>org.hibernate.persister.ClassPersister</literal> que implemente
+                la persistencia por medio, por ejemplo, de llamadas a procedimientos almacenados, serializaci&#x00f3;n a
+                ficheros planos o LDAP. Para un ejemplo simple (de persistencia a una  <literal>Hashtable</literal>) mira 
+                <literal>org.hibernate.test.CustomPersister</literal>.
+            </para>
+            
+            <para>
+                Observa que los valores de <literal>dynamic-update</literal> y <literal>dynamic-insert</literal>
+                no son heredados por las subclases y por lo tanto deben especificarse en los elementos
+                <literal>&lt;subclass&gt;</literal> o <literal>&lt;joined-subclass&gt;</literal>.
+                Estos ajustes pueden incrementar el rendimiento en algunos casos, pero podr&#x00ed;an mermarlo en otros.
+                Ten juicio en su uso.
+            </para>
+            
+            <para>
+                Generalmente el uso de <literal>select-before-update</literal> disminuir&#x00e1; el rendimiento.
+                Es muy &#x00fa;til prevenir que se llame innecesariamente a un disparador de actualizaci&#x00f3;n de
+                base de datos al volver a unir un grafo de instancias separadas a una <literal>Session</literal>.
+            </para>
+            
+            <para>
+                Si habilitas <literal>dynamic-update</literal>, tendr&#x00e1;s opci&#x00f3;n de estrategias
+                de bloqueo optimistas:
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <literal>version</literal> chequea las columnas de versi&#x00f3;n/timestamp
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>all</literal> chequea todas las columnas
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>dirty</literal> chequea las columnas modificadas, permitiendo algunas
+                        actualizaciones concurrentes
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>none</literal> no usa bloqueo optimista
+                    </para>
+                </listitem>
+            </itemizedlist>
+            <para>
+                Recomendamos <emphasis>muy</emphasis> fuertemente que uses columnas de
+                versi&#x00f3;n/timestamp para bloqueo optimista con Hibernate. Esta es la estrategia
+                &#x00f3;ptima con respecto al rendimiento y es la &#x00fa;nica estrategia que maneja
+                correctamente las modificaciones hechas a las instancias separadas.
+                (por ejemplo, cuando se usa <literal>Session.merge()</literal>).
+            </para>
+
+            <para>
+                Para un mapeo de Hibernate, no hay diferencia entre una vista y una tabla base.
+                Como se supone esto es transparente a nivel de base de datos (observa que algunos
+                DBMS no soportan correctamente las vistas, especialmente con las actualizaciones).
+                A veces quieres usar una vista, pero no puedes crear una en la base de datos
+                (por ejemplo, con un esquema heredado). En este caso, puedes mapear una entidad inmutable
+                de s&#x00f3;lo lectura a una expresi&#x00f3;n de subconsulta SQL dada.
+            </para>
+
+            <programlisting><![CDATA[<class name="Summary">
+    <subselect>
+        select item.name, max(bid.amount), count(*)
+        from item
+        join bid on bid.item_id = item.id
+        group by item.name
+    </subselect>
+    <synchronize table="item"/>
+    <synchronize table="bid"/>
+    <id name="name"/>
+    ...
+</class>]]></programlisting>
+
+            <para>
+                Declara las tablas con las que sincronizar esta entidad, asegurando que el auto-flush
+                ocurre correctamente, y que las consultas contra la entidad derivada no devuelven datos
+                desactualizados. El <literal>&lt;subselect&gt;</literal> est&#x00e1; disponible tanto
+                como un atributo o como un elemento anidado de mapeo.
+            </para>
+
+        </sect2>
+
+        <sect2 id="mapping-declaration-id" revision="3">
+            <title>id</title>
+
+            <para>
+                Las clases mapeadas <emphasis>deben</emphasis> declarar la columna de clave primaria de la tabla
+                de la base de datos. En la mayor&#x00ed;a de los casos tendr&#x00e1; tambi&#x00e9;n una propiedad
+                estilo Javabeans que tenga el identificador &#x00fa;nico de una instancia. El elemento
+                <literal>&lt;id&gt;</literal> define el mapeo de esa propiedad a la columna de clave primaria.
+            </para>
+            
+            <programlistingco>
+                <areaspec>
+                    <area id="id1" coords="2 70"/>
+                    <area id="id2" coords="3 70" />
+                    <area id="id3" coords="4 70"/>
+                    <area id="id4" coords="5 70" />
+                    <area id="id5" coords="6 70" />
+                </areaspec>
+                <programlisting><![CDATA[<id
+        name="propertyName"
+        type="typename"
+        column="column_name"
+        unsaved-value="null|any|none|undefined|id_value"
+        access="field|property|ClassName"
+        node="element-name|@attribute-name|element/@attribute|.">
+
+        <generator class="generatorClass"/>
+</id>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="id1">
+                        <para>
+                            <literal>name</literal> (opcional): El nombre de la propiedad del indentificador.
+                        </para>
+                    </callout>
+                    <callout arearefs="id2">
+                        <para>
+                            <literal>type</literal> (opcional): Un nombre que indica el tipo Hibernate.
+                        </para>
+                    </callout>
+                    <callout arearefs="id3">
+                        <para>
+                            <literal>column</literal> (opcional - por defecto al nombre de la propiedad): 
+                            El nombre de la columna de clave primaria.
+                        </para>
+                    </callout>
+                    <callout arearefs="id4">
+                        <para>
+                            <literal>unsaved-value</literal> (opcional - por defecto al valor "sensible"): 
+                            Una valor de la propiedad identificadora que indica que una instancia est&#x00e1;
+                            reci&#x00e9;n instanciada (sin salvar), distingui&#x00e9;ndola de instancias separadas
+                            que fueran salvadas o cargadas en una sesi&#x00f3;n previa.
+                        </para>
+                    </callout>            
+                   <callout arearefs="id5">
+                        <para>
+                            <literal>access</literal> (opcional - por defecto a <literal>property</literal>):
+                            La estrategia que Hibernate debe usar para acceder al valor de la propiedad.
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+            
+            <para>
+                Si se omite el atributo <literal>name</literal>, se asume que la clase no tiene propiedad
+                identificadora.
+            </para>
+            
+            <para>
+                El atributo <literal>unsaved-value</literal> es importante! Si la propiedad identificadora de tu
+                clase no tiene por defecto el valor por defecto normal de Java (null o cero), entonces debes especificar
+                el valor por defecto real.
+            </para>
+
+             <para>
+                Hay una declaraci&#x00f3;n <literal>&lt;composite-id&gt;</literal> alternativa para permitir acceso
+                a datos heredados con claves compuestas. Desalentamos fuertemente su uso para cualquier otra cosa.
+            </para>
+            
+            <sect3 id="mapping-declaration-id-generator" revision="2">
+                <title>Generator</title>
+
+                <para>
+                    El elemento hijo opcional <literal>&lt;generator&gt;</literal> nombra una clase Java
+                    usada en generar identificadores &#x00fa;nicos para instancias de la clase persistente.
+                    De requerirse alg&#x00fa;n par&#x00e1;metro para configurar o inicializar la instancia del generador,
+                    se pasa usando el elemento <literal>&lt;param&gt;</literal>.
+                </para>
+
+                <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+        <generator class="org.hibernate.id.TableHiLoGenerator">
+                <param name="table">uid_table</param>
+                <param name="column">next_hi_value_column</param>
+        </generator>
+</id>]]></programlisting>
+
+                <para>
+                    Todos los generadores implementan la interface <literal>org.hibernate.id.IdentifierGenerator</literal>.
+                    Esta es una interface muy simple; algunas aplicaciones pueden escoger proveer sus propias
+                    implementaciones especializadas. Sin embargo, Hibernate provee un rango de implementaciones
+                    prefabricadas. Hay nombres alias de atajo para los generadores prefabricados:
+                    <variablelist>
+                        <varlistentry>
+                        <term><literal>increment</literal></term>
+                        <listitem>
+                            <para>
+                                genera indentificadores de tipo <literal>long</literal>, <literal>short</literal> o
+                                <literal>int</literal> que s&#x00f3;lo son &#x00fa;nicos cuando ning&#x00fa;n otro proceso
+                                est&#x00e1; insertando datos en la misma tabla. <emphasis>No usar en un cluster.</emphasis>
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>identity</literal></term>
+                        <listitem>
+                            <para>
+                                soporta columnas de identidad en DB2, MySQL, MS SQL Server, Sybase y
+                                HypersonicSQL. El identificador devuelto es de tipo <literal>long</literal>,
+                                <literal>short</literal> o <literal>int</literal>.
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>sequence</literal></term>
+                        <listitem>
+                            <para>
+                                usa una secuencia en DB2, PostgreSQL, Oracle, SAP DB, McKoi o un generador
+                                en Interbase. El identificador devuelto es de tipo <literal>long</literal>,
+                                <literal>short</literal> o <literal>int</literal>.
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>hilo</literal></term>
+                        <listitem>
+                            <para id="mapping-declaration-id-hilodescription" revision="1">
+                                usa un algoritmo alto/bajo para generar eficientemente identificadores de tipo
+                                <literal>long</literal>, <literal>short</literal> o <literal>int</literal>,
+                                dada una tabla y columna como fuente de valores altos (por defecto
+                                <literal>hibernate_unique_key</literal> y <literal>next_hi</literal> respectivamente).
+                                El algoritmo alto/bajo genera identificadores que son &#x00fa;nicos s&#x00f3;lo para una
+                                base de datos particular.
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>seqhilo</literal></term>
+                        <listitem>
+                            <para>
+                                usa un algoritmo alto/bajo para generar eficientemente identificadores de tipo
+                                <literal>long</literal>, <literal>short</literal> o <literal>int</literal>,
+                                dada una secuencia de base de datos.
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>uuid</literal></term>
+                        <listitem>
+                            <para>
+                                usa un algoritmo UUID de 128 bits para generar identificadore de tipo
+                                cadena, &#x00fa;nicos en una ref (se usa la direcc&#x00f3;n IP). El UUID
+                                se codifica como una cadena hexadecimal de 32 d&#x00ed;gitos de largo.
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>guid</literal></term>
+                        <listitem>
+                            <para>
+                                usa una cadena GUID generada por base de datos en MS SQL Server y MySQL.
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>native</literal></term>
+                        <listitem>
+                            <para>
+                                selecciona <literal>identity</literal>, <literal>sequence</literal> o
+                                <literal>hilo</literal> dependiendo de las capacidades de la base de datos
+                                subyacente.
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>assigned</literal></term>
+                        <listitem>
+                            <para>
+                                deja a la aplicaci&#x00f3;n asignar un identificador al objeto antes
+                                de que se llame a <literal>save()</literal>. Esta es la estrategia
+                                por defecto si no se especifica un elemento <literal>&lt;generator&gt;</literal>.
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>select</literal></term>
+                        <listitem>
+                            <para>
+                                recupera una clave primaria asignada por un disparador de base de datos
+                                seleccionando la fila por alguna clave &#x00fa;nica y recuperando el valor de
+                                la clave primaria.
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                        <term><literal>foreign</literal></term>
+                        <listitem>
+                            <para>
+                                usa el identificador de otro objeto asociado. Generalmente usado en conjunc&#x00f3;n
+                                a una asociac&#x00f3;n de clave primaria <literal>&lt;uno-a-uno&gt;</literal>
+                            </para>
+                        </listitem>
+                        </varlistentry>
+                    </variablelist>
+
+                </para>
+            </sect3>
+            
+            <sect3 id="mapping-declaration-id-hilo" revision="1">
+                <title>Algoritmo alto/bajo</title>
+                <para>
+                    Los generadores <literal>hilo</literal> y <literal>seqhilo</literal> proveen dos implementaciones
+                    alternativas del algoritmo alto/bajo, un enfoque favorito en generaci&#x00f3;n de identificadores.
+                    La primera implementaci&#x00f3;n requiere de una tabla "especial" de base de datos para tener el siguiente
+                    valor "alto" disponible.
+                    La segunda usa una secuencia del estilo de Oracle (donde se soporte).
+                </para>
+
+                <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+        <generator class="hilo">
+                <param name="table">hi_value</param>
+                <param name="column">next_value</param>
+                <param name="max_lo">100</param>
+        </generator>
+</id>]]></programlisting>
+
+                <programlisting><![CDATA[<id name="id" type="long" column="cat_id">
+        <generator class="seqhilo">
+                <param name="sequence">hi_value</param>
+                <param name="max_lo">100</param>
+        </generator>
+</id>]]></programlisting>
+
+                <para>
+                    Desafortunadamente, no puedes usar <literal>hilo</literal> cuando le proveas tu propia
+                    <literal>Connection</literal> a Hibernate. Cuando Hibernate est&#x00e1; usando un datasource
+                    del servidor de aplicaciones para obtener conexiones alistadas con JTA, debes configurar
+                    correctamente el <literal>hibernate.transaction.manager_lookup_class</literal>.
+                </para>
+            </sect3>
+            
+            <sect3 id="mapping-declaration-id-uuid">
+                <title>Algoritmo UUID</title>
+                <para>
+                    El UUID contiene: la direcci&#x00f3;n IP, el instante de arranque de la JVM
+                    (con una precisi&#x00f3;n de un cuarto de segundo), el tiempo de sistema y un valor
+                    de contador (&#x00fa;nico en la JVM). No es posible obtener una direcci&#x00f3;n MAC o
+                    una direcci&#x00f3;n de memoria desde c&#x00f3;digo Java, as&#x00ed; que esto es lo mejor
+                    que podemos hacer sin usar JNI.
+                </para>
+            </sect3>
+
+            <sect3 id="mapping-declaration-id-sequences">
+            <title>Columnas de identidad y secuencias</title>
+                <para>
+                    Para las bases de datos que soportan columnas de identidad (DB2, MySQL, Sybase, MS SQL),
+                    puedes usar generaci&#x00f3;n de claves <literal>identity</literal>. Para las bases de datos
+                    que soportan secuencias (DB2, Oracle, PostgreSQL, Interbase, McKoi, SAP DB) puedes usar la generaci&#x00f3;n
+                    de claves del estilo <literal>sequence</literal>. Ambas estrategias requieren dos consultas SQL
+                    para insertar un nuevo objeto.
+                </para>
+
+                <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+        <generator class="sequence">
+                <param name="sequence">person_id_sequence</param>
+        </generator>
+</id>]]></programlisting>
+
+                <programlisting><![CDATA[<id name="id" type="long" column="person_id" unsaved-value="0">
+        <generator class="identity"/>
+</id>]]></programlisting>
+            
+                <para>
+                    Para desarrollos multiplataforma, la estrategia <literal>native</literal>
+                    eiligir&#x00e1; de entre las estrategias <literal>identity</literal>,
+                    <literal>sequence</literal> y <literal>hilo</literal>, dependiendo de las capacidades
+                    de la base de datos subyacentes.
+                </para>
+            </sect3>
+            
+            <sect3 id="mapping-declaration-id-assigned">
+                <title>Identificadores asignados</title>
+                <para>
+                    Si quieres que la aplicaci&#x00f3;n asigne los identificadores (en contraposici&#x00f3;n
+                    a que los genere Hibernate), puedes usar el generador <literal>assigned</literal>.
+                    Este generador especial usar&#x00e1; el valor identificador ya asignado a la
+                    propiedad identificadora del objeto. Este generador se usa cuandola clave primaria es
+                    una clave natural en vez de una clave sustituta. Este es el comportamiento por defecto si
+                    no especificas un elemento <literal>&lt;generator&gt;</literal>.
+                </para>
+                
+                <para>
+                    Elegir el generador <literal>assigned</literal> hace que Hibernate use
+                    <literal>unsaved-value="undefined"</literal>, forzando a Hibernate a ir 
+                    a la base de datos para determinar si una instancia es transitoria o separada,
+                    a menos que haya una propiedad de versi&#x00f3;n o timestamp, o que tu definas 
+                    <literal>Interceptor.isUnsaved()</literal>.
+                </para>
+            </sect3>
+
+            <sect3 id="mapping-declaration-id-select">
+                <title>Claves primarias asignadas por disparadores</title>
+                <para>
+                    Para esquemas heredados solamente (Hibernate no genera DDL con disparadores).
+                </para>
+
+                <programlisting><![CDATA[<id name="id" type="long" column="person_id">
+        <generator class="select">
+                <param name="key">socialSecurityNumber</param>
+        </generator>
+</id>]]></programlisting>
+
+                <para>
+                    En el ejemplo de arriba, hay una propiedad &#x00e1;nica llamada
+                    <literal>socialSecurityNumber</literal> definida por la clase, como 
+                    una clave natural, y una clave sustituta llamada <literal>person_id</literal>
+                    cuyo valor es generado por un disparador.
+                </para>
+                
+            </sect3>
+
+        </sect2>
+
+        <sect2 id="mapping-declaration-compositeid" revision="2">
+            <title>composite-id</title>
+
+            <programlisting><![CDATA[<composite-id
+        name="propertyName"
+        class="ClassName"
+        unsaved-value="undefined|any|none"
+        access="field|property|ClassName"
+        node="element-name|.">
+
+        <key-property name="propertyName" type="typename" column="column_name"/>
+        <key-many-to-one name="propertyName class="ClassName" column="column_name"/>
+        ......
+</composite-id>]]></programlisting>
+
+            <para>
+                Para una tabla con clave compuesta, puedes mapear m&#x00fa;ltiples propiedades
+                de la clase como propiedades identificadoras. El elemento <literal>&lt;composite-id&gt;</literal>
+                acepta los mapeos de propiedad <literal>&lt;key-property&gt;</literal> y
+                los mapeos <literal>&lt;key-many-to-one&gt;</literal> como elementos hijo.
+            </para>
+            
+            <programlisting><![CDATA[<composite-id>
+        <key-property name="medicareNumber"/>
+        <key-property name="dependent"/>
+</composite-id>]]></programlisting>
+
+            <para>
+                Tu clase persistente <emphasis>debe</emphasis> sobreescribir <literal>equals()</literal>
+                y <literal>hashCode()</literal> para implementar igualdad de identificador compuesto.
+                Debe tambi&#x00e9;n implementar <literal>Serializable</literal>.
+            </para>
+
+            <para>
+                Desafortunadamente, este enfoque de identificadores compuestos significa que un objeto
+                persistente es su propio identificador. No existe otra "asa" conveniente m&#x00e1;s que el
+                objeto mismo. Debes instanciar una instancia de la clase misma y poblar sus propiedades
+                identificadoras antes que puedas <literal>load()</literal> el estado persistente asociado
+                a una clave compuesta. Describiremos un enfoque mucho m&#x00e1;s conveniente donde el identificador
+                compuesto est&#x00e1; implementado como una clase separada en <xref linkend="components-compositeid"/>.
+                Los atributos descriptos debajo solamente se aplican a este enfoque alternativo:
+            </para>
+
+            <itemizedlist spacing="compact">
+                <listitem>
+                    <para>
+                        <literal>name</literal> (opcional): Una propiedad de tipo componente que tiene el identificador
+                        compuesto (ver siguiente secci&#x00f3;n).
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>class</literal> (opcional - por defecto al tipo de la propiedad determinado
+                        por reflecci&#x00f3;n): La clase del componente usado como identificador compuesto (ver siguiente secci&#x00f3;n).
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>unsaved-value</literal> (opcional - por defecto a <literal>undefined</literal>): 
+                        Indica que las instancias transitorias deben ser consideradas como reci&#x00e9;n instanciadas,
+                        si se establece a <literal>any</literal>, o separadas, si se establece a <literal>none</literal>.
+                        Lo mejor
+                        
+                        Indicates that transient instances should be considered newly instantiated, if set 
+                        to <literal>any</literal>, or detached, if set to <literal>none</literal>.
+                        Lo mejor en todos los casos es dejar el valor por defecto.
+                    </para>
+                </listitem>
+            </itemizedlist>
+            
+        </sect2>
+        
+        <sect2 id="mapping-declaration-discriminator" revision="3">
+            <title>discriminator</title>
+
+            <para>
+                El elemento <literal>&lt;discriminator&gt;</literal> es requerido para la persistencia
+                polim&#x00f3;rfica usando la estrategia de mapeo de tabla-por-jerarqu&#x00ed;a-de-clases y
+                declara una columna discriminadora de la tabla. La columna discriminidora contiene valores
+                de marca que le dicen a la capa de persistencia qu&#x00e9; subclase instanciar para una fila
+                en particular. Un conjunto restringido de tipos puede ser usado:
+                <literal>string</literal>, <literal>character</literal>, <literal>integer</literal>, 
+                <literal>byte</literal>, <literal>short</literal>, <literal>boolean</literal>, 
+                <literal>yes_no</literal>, <literal>true_false</literal>.
+            </para>
+            
+            <programlistingco>
+                <areaspec>
+                    <area id="discriminator1" coords="2 60"/>
+                    <area id="discriminator2" coords="3 60" />
+                    <area id="discriminator3" coords="4 60" />
+                    <area id="discriminator4" coords="5 60" />
+                    <area id="discriminator5" coords="6 60" />
+                </areaspec>
+                <programlisting><![CDATA[<discriminator
+        column="discriminator_column"
+        type="discriminator_type"
+        force="true|false"
+        insert="true|false"
+        formula="arbitrary sql expression"
+/>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="discriminator1">
+                        <para>
+                            <literal>column</literal> (opcional - por defecto a <literal>class</literal>) el
+                            nombre de la columna discriminadora.
+                        </para>
+                    </callout>
+                    <callout arearefs="discriminator2">
+                        <para>
+                            <literal>type</literal> (opcional - por defecto a <literal>string</literal>) un
+                            nombre que indique el tipo Hibernate
+                        </para>
+                    </callout>          
+                    <callout arearefs="discriminator3">
+                        <para>
+                            <literal>force</literal> (optconal - por defecto a <literal>false</literal>) 
+                            "fuerza" a Hibernate a especificar valores discriminadores permitidos incluso
+                            cuando se recuperan todas las instancias de la clase ra&#x00ed;z.
+                        </para>
+                    </callout>          
+                    <callout arearefs="discriminator4">
+                        <para>
+                            <literal>insert</literal> (opcional - por defecto a <literal>true</literal>)
+                            establezca este a <literal>false</literal> si tu columna discriminadora es
+                            tambi&#x00e9;n parte de un identificador mapeado compuesto. (Le dice a Hibernate
+                            que no incluya la columna en los SQL <literal>INSERT</literal>s.)
+                        </para>
+                    </callout>
+                    <callout arearefs="discriminator5">
+                        <para>
+                            <literal>formula</literal> (opcional) una expresi&#x00f3;n SQL arbitraria que
+                            es ejecutada cuando un tipo tenga que ser evaluado. Permite dicriminaci&#x00f3;n
+                            basada en el contenido.
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+
+            <para>
+                Los valores reales de la columna discriminadora est&#x00e1;n especificados por
+                el atributo <literal>discriminator-value</literal> de los elementos
+                <literal>&lt;class&gt;</literal> y <literal>&lt;subclass&gt;</literal>.
+            </para>
+            
+            <para>
+                El atributo <literal>force</literal> es (s&#x00f3;lo) &#x00fa;til si la tabla contiene
+                filas con valores discriminadores "extra" que no est&#x00e1;n mapeados a la clase
+                persistente. Generalmente este no es el caso.
+            </para>
+
+            <para>
+                Usando el atributo <literal>formula</literal> puedes declarar una expresi&#x00f3;n SQL
+                arbitraria que ser&#x00e1; usada para evaluar el tipo de una fila:
+            </para>
+
+            <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" revision="1">
+            <title>version (opcional)</title>
+            
+            <para>
+                El elemento <literal>&lt;version&gt;</literal> es opcional e indica que la
+                tabla contiene datos versionados. Esto es particularmente &#x00fa;til si planeas
+                usar <emphasis>transacciones largas</emphasis> (ver debajo).
+            </para>
+            
+            <programlistingco>
+                <areaspec>
+                    <area id="version1" coords="2 70"/>
+                    <area id="version2" coords="3 70"/>
+                    <area id="version3" coords="4 70"/>
+                    <area id="version4" coords="5 70"/>
+                    <area id="version5" coords="6 70"/>
+                </areaspec>
+                <programlisting><![CDATA[<version
+        column="version_column"
+        name="propertyName"
+        type="typename"
+        access="field|property|ClassName"
+        unsaved-value="null|negative|undefined"
+        node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="version1">
+                        <para>
+                            <literal>column</literal> (opcional - por defecto al nombre de la propiedad): El nombre
+                            de la columna que tiene el n&#x00fa;mero de versi&#x00f3;n.
+                        </para>
+                    </callout>          
+                    <callout arearefs="version2">
+                        <para>
+                            <literal>name</literal>: El nombre de una propiedad de la clase persistente.
+                        </para>
+                    </callout>
+                    <callout arearefs="version3">
+                        <para>
+                            <literal>type</literal> (opcional - por defecto a <literal>integer</literal>): 
+                            El tipo del n&#x00fa;.mero de vesi&#x00f3;n.
+                        </para>
+                    </callout>          
+                   <callout arearefs="version4">
+                        <para>
+                            <literal>access</literal> (opcional - por defecto a <literal>property</literal>): La
+                            estrategia que Hibernate debe usar para acceder al valor de la propiedad.
+                        </para>
+                    </callout>
+                   <callout arearefs="version5">
+                        <para>
+                            <literal>unsaved-value</literal> (opcional - por defecto a <literal>undefined</literal>):
+                            Un valor de la propiedad de versi&#x00f3;n que indica que una instancia est&#x00e1;
+                            reci&#x00e9;n instanciada (sin guardar), distingui&#x00e9;ndola de instancias
+                            separadas que fueran guardadas o cargadas en una sesi&#x00f3;n previa.
+                            (<literal>undefined</literal> especifica que debe usarse el valor de la
+                            propiedad identificadora.)
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+            
+            <para>
+                Los n&#x00fa;meros de versi&#x00f3;n deben ser de tipo <literal>long</literal>,
+                <literal>integer</literal>, <literal>short</literal>, <literal>timestamp</literal> o
+                <literal>calendar</literal> de Hibernate.
+            </para>
+            
+            <para>
+                Una propiedad de versi&#x00f3;n o timestamp nunca debe ser nula para una instancia
+                separada, de modo que Hibernate detectar&#x00e1; cualquier instancia con una versi&#x00f3;n
+                o timestamp nulo como transitoria, sin importar qu&#x00e9; otras estrategias
+                <literal>unsaved-value</literal> se hayan especificado.
+                <emphasis>Declarar una propiedad de vers&#x00f3;n o timestamp nulable es una forma
+                f&#x00e1;cil de evitar cualquier problema con la re-uni&#x00f3;n transitiva en Hibernate,
+                especialmente &#x00fa;til para que usa identificadores asignados o claves compuestas!</emphasis>
+            </para>
+        </sect2>
+        
+        <sect2 id="mapping-declaration-timestamp">
+            <title>timestamp (opcional)</title>
+
+            <para>
+                El elemento opcional <literal>&lt;timestamp&gt;</literal> indica que la tabla contiene
+                datos con sellos de tiempo. Esto esta concebido como una alternativa al versionado.
+                Los timestamps (sellos de tiempo) son por su naturaleza una implementaci&#x00f3;n menos
+                segura de bloqueo optimista. Sin embrago, a veces la aplicaci&#x00f3;n puede usar los
+                timestamps en otras formas.
+            </para>
+            
+            <programlistingco>
+                <areaspec>
+                    <area id="timestamp1" coords="2 70"/>
+                    <area id="timestamp2" coords="3 70" />
+                    <area id="timestamp3" coords="4 70" />
+                    <area id="timestamp4" coords="5 70" />
+                </areaspec>            
+                <programlisting><![CDATA[<timestamp
+        column="timestamp_column"
+        name="propertyName"
+        access="field|property|ClassName"
+        unsaved-value="null|undefined"
+        node="element-name|@attribute-name|element/@attribute|."
+/>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="timestamp1">
+                        <para>
+                            <literal>column</literal> (opcional - por defecto al nombre de la propiedad): El nombre
+                            de una columna que tiene el timestamp.
+                        </para>
+                    </callout>                   
+                    <callout arearefs="timestamp2">
+                        <para>
+                            <literal>name</literal>: El nombre de una propiedad del estilo JavaBeans de tipo
+                            Java <literal>Date</literal> o <literal>Timestamp</literal> de la clase persistente.
+                        </para>
+                    </callout>
+                   <callout arearefs="timestamp3">
+                        <para>
+                            <literal>access</literal> (opcional - por defecto a <literal>property</literal>): La
+                            estrategia que Hibernate debe usar para acceder al valor de la propiedad.
+                        </para>
+                    </callout>
+                   <callout arearefs="timestamp4">
+                        <para>
+                            <literal>unsaved-value</literal> (opcional - por defecto a <literal>null</literal>): 
+                            Un valor de propiedad de versi&#x00f3;n que indica que una instancia est&#x00e1;
+                            reci&#x00e9;n instanciada (sin guardar), distingui&#x00e9;ndola de instancias separadas
+                            que hayan sido guardadas o cargadas en una sesi&#x00f3;n previa.
+                            (<literal>undefined</literal> especifica que debe usarse el valor de la propiedad
+                            identificadora.)
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+            
+            <para>
+                Note that <literal>&lt;timestamp&gt;</literal> is equivalent to 
+                <literal>&lt;version type="timestamp"&gt;</literal>.
+            </para>
+        </sect2>
+
+
+        <sect2 id="mapping-declaration-property" revision="2">
+            <title>property</title>
+
+            <para>
+                El elemento <literal>&lt;property&gt;</literal> declara una propiedad persistente estilo
+                JavaBean de la clase.
+            </para>
+            
+            <programlistingco>
+                <areaspec>
+                    <area id="property1" coords="2 70"/>
+                    <area id="property2" coords="3 70"/>
+                    <area id="property3" coords="4 70"/>
+                    <areaset id="property4-5" coords="">
+                        <area id="property4" coords='5 70'/>
+                        <area id="property5" coords='6 70'/>
+                    </areaset>
+                    <area id="property6" coords="7 70"/>
+                    <area id="property7" coords="8 70"/>
+                    <area id="property8" coords="9 70"/>
+                    <area id="property9" coords="10 70"/>
+                    <area id="property10" coords="11 70"/>
+                    <area id="property11" coords="12 70"/>
+                </areaspec>            
+                <programlisting><![CDATA[<property
+        name="propertyName"
+        column="column_name"
+        type="typename"
+        update="true|false"
+        insert="true|false"
+        formula="arbitrary SQL expression"
+        access="field|property|ClassName"
+        lazy="true|false"
+        unique="true|false"
+        not-null="true|false"
+        optimistic-lock="true|false"
+        node="element-name|@attribute-name|element/@attribute|."
+        index="index_name"
+        unique_key="unique_key_id"
+        length="L"
+        precision="P"
+        scale="S"
+/>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="property1">
+                        <para>
+                            <literal>name</literal>: el nombre de la propiedad, con la letra inicial
+                            en min&#x00fa;sculas.
+                        </para>
+                    </callout>                   
+                    <callout arearefs="property2">
+                        <para>
+                            <literal>column</literal> (opcional - por defecto al nombre de la propiedad): el nombre
+                            de la columna de tabla de base de datos mapeada. Esto puede tambi&#x00e9;n ser especificado
+                            con elemento(s) <literal>&lt;column&gt;</literal> anidado(s).
+                        </para>
+                    </callout>
+                    <callout arearefs="property3">
+                        <para>
+                            <literal>type</literal> (opcional): un nombre que indica el nobre Hibernate.
+                        </para>
+                    </callout>
+                    <callout arearefs="property4-5">
+                        <para>
+                            <literal>update, insert</literal> (opcional - por defecto a <literal>true</literal>) :
+                            especifica que las columnas mapeadas deben ser inclu&#x00ed;das en las sentencias SQL
+                            <literal>UPDATE</literal> y/o <literal>INSERT</literal> . Especificando ambas a 
+                            <literal>false</literal> permite una propiedad "derivada" cuyo valor es inicializado desde
+                            alguna otra propiedad que mapee a la misma columna (o columnas) o por un disparador u otra
+                            aplicaci&#x00f3;n.
+                        </para>
+                    </callout>
+                    <callout arearefs="property6">
+                        <para>
+                            <literal>formula</literal> (opcional): una expresi&#x00f3;n SQL que define el valor
+                            para una propiedad <emphasis>computada</emphasis>. Las propiedades computadas no tienen
+                            una columna mapeada propia.
+                        </para>
+                    </callout>
+                   <callout arearefs="property7">
+                        <para>
+                            <literal>access</literal> (opcional - por defecto a <literal>property</literal>): La
+                            estrategia que Hibernate debe usar para acceder al valor de la propiedad.
+                        </para>
+                    </callout>
+                   <callout arearefs="property8">
+                        <para>
+                            <literal>lazy</literal> (opcional - por defecto a <literal>false</literal>): Especifica
+                            que esta propiedad debe ser tra&#x00ed;da perezosamente cuando la variable de instancia
+                            sea accedida por primera vez (requiere instrumentaci&#x00f3;n en tiempo de compilaci&#x00f3;n).
+                        </para>
+                    </callout>
+                    <callout arearefs="property9">
+                        <para>
+                            <literal>unique</literal> (opcional): Habilita la generaci&#x00f3; DDL de una restricci&#x00f3;n
+                            de unicidad para las columnas. Adem&#x00e1;s, permite que &#x00e9;sta sea un blanco objetivo de
+                            una <literal>property-ref</literal>.
+                        </para>
+                    </callout>
+                    <callout arearefs="property10">
+                        <para>
+                            <literal>not-null</literal> (opcional): Habilita la generaci&#x00f3; DDL de una restricci&#x00f3;n
+                            de nulabilidad para las columnas.
+                        </para>
+                    </callout>
+                    <callout arearefs="property11">
+                        <para>
+                            <literal>optimistic-lock</literal> (opcional - por defecto a <literal>true</literal>): 
+                            Especifica que las actualizaciones a esta propiedad requieran o no de la obtenci&#x000f3;n
+                            de un bloqueo optimista. En otras palabras, determina si debe ocurrir un incremento de versi&#x00f3;n
+                            cuando la propiedad este sucia (desactualizada).
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+
+            <para>
+                <emphasis>typename</emphasis> puede ser:
+            </para>
+
+            <orderedlist spacing="compact">
+                <listitem>
+                    <para>
+                        El nombre de un tipo b&#x00e1;sico Hibernate (por ejemplo, <literal>integer, string, character,
+                        date, timestamp, float, binary, serializable, object, blob</literal>).
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        El nombre de una clase Java de tipo b&#x00e1;sico (por ejemplo, <literal>int, float,
+                        char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob</literal>).
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        El nombre de una clase Java serializable.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        El nombre de un tipo personalizado (por ejemplo, <literal>com.illflow.type.MyCustomType</literal>).
+                    </para>
+                </listitem>
+            </orderedlist>
+
+            <para>
+                Si no especificas un tipo, Hibernate usar&#x00e1; reflecci&#x00f3;n sobre la 
+                propiedad mencionada para deducir el tipo Hibernate correcto. Hibernate intentar&#x00e1;
+                interpretar el nombre de la clase de retorno del getter de la propiedad usando las reglas
+                2, 3 y 4 en ese orden. Sin embargo, esto no siempre suficiente. En ciertos casos, necesitar&#x00e1;s
+                a&#x00fa;n el atributo <literal>type</literal>. (Por ejemplo, para distinguir entre
+                <literal>Hibernate.DATE</literal> y <literal>Hibernate.TIMESTAMP</literal>,
+                o especificar un tipo personalizado.)
+            </para>
+            
+            <para>
+                El atributo <literal>access</literal> te deja controlar c&#x00f3;mo Hibernate
+                acceder&#x00e1; a la propiedad en tiempo de ejecuci&#x00f3;n. Por defecto, Hibernate
+                llamar&#x00e1; al par de getter/setter de la propiedad. Si especificas
+                <literal>access="field"</literal>, Hibernate se saltar&#x00e1; el par get/set y 
+                acceder&#x00e1; al campo directamente usando reflecci&#x00f3;n. Puedes especificar tu
+                propia estrategia de acceso a la propiedad mencionando una clase que implemente
+                la interface <literal>org.hibernate.property.PropertyAccessor</literal>.
+            </para>
+
+            <para>
+                Una aspecto especialmente poderoso son las propiedades derivadas. Estas propiedades
+                son por definici&#x00f3;n de s&#x00f3;lo lectura, el valor de la propiedad es computado
+                en tiempo de carga. Tu declaras la computaci&#x00f3;n como una expresi&#x00f3;n SQL,
+                y &#x00e9;sta se traduce a cl&#x00e1;usula de subconsulta <literal>SELECT</literal>
+                en la consulta SQL que cargue una instancia:
+            </para>
+
+        <programlisting><![CDATA[
+<property name="totalPrice"
+    formula="( SELECT SUM (li.quantity*p.price) FROM LineItem li, Product p
+                WHERE li.productId = p.productId
+                AND li.customerId = customerId
+                AND li.orderNumber = orderNumber )"/>]]></programlisting>
+
+            <para>
+                Observa que puedes referenciar la propia tabla de las entidades sin declarar un alias
+                o una columna particular (<literal>customerId</literal> en el ejemplo dado). Observa
+                adem&#x00e1;s que puedes usar el elemento anidado de mapeo <literal>&lt;formula&gt;</literal>
+                si no te gusta usar el atributo.
+            </para>
+
+        </sect2>
+
+        <sect2 id="mapping-declaration-manytoone" revision="3">
+            <title>many-to-one</title>
+
+            <para>
+                Una asociaci&#x00f3;n ordinaria a otra clase persistente se declara usando
+                el elemento <literal>many-to-one</literal>. El modelo relacional es una
+                asociaci&#x00f3;n muchos-a-uno: una clave for&#x00e1;nea en una tabla est&#x00e1;
+                referenciando la columna (o columnas) de la clave primaria de la tabla objetivo.
+            </para>
+
+            <programlistingco>
+                <areaspec>
+                    <area id="manytoone1" coords="2 70"/>
+                    <area id="manytoone2" coords="3 70"/>
+                    <area id="manytoone3" coords="4 70"/>
+                    <area id="manytoone4" coords="5 70"/>
+                    <area id="manytoone5" coords="6 70"/>
+                    <areaset id="manytoone6-7" coords="">
+                        <area id="manytoone6" coords='7 70'/>
+                        <area id="manytoone7" coords='8 70'/>
+                    </areaset>
+                    <area id="manytoone8" coords="9 70"/>
+                    <area id="manytoone9" coords="10 70"/>
+                    <area id="manytoone10" coords="11 70"/>
+                    <area id="manytoone11" coords="12 70"/>
+                    <area id="manytoone12" coords="13 70"/>
+                    <area id="manytoone13" coords="14 70"/>
+                    <area id="manytoone14" coords="15 70"/>
+                    <area id="manytoone15" coords="16 70"/>
+                    <area id="manytoone16" coords="17 70"/>
+                </areaspec>
+                <programlisting><![CDATA[<many-to-one
+        name="propertyName"
+        column="column_name"
+        class="ClassName"
+        cascade="cascade_style"
+        fetch="join|select"
+        update="true|false"
+        insert="true|false"
+        property-ref="propertyNameFromAssociatedClass"
+        access="field|property|ClassName"
+        unique="true|false"
+        not-null="true|false"
+        optimistic-lock="true|false"
+        lazy="true|proxy|false"
+        not-found="ignore|exception"
+        entity-name="EntityName"
+        formula="cualquier expresi&#x00f3;n SQL"
+        node="element-name|@attribute-name|element/@attribute|."
+        embed-xml="true|false"
+        index="index_name"
+        unique_key="unique_key_id"
+        foreign-key="foreign_key_name"
+/>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="manytoone1">
+                        <para>
+                            <literal>name</literal>: El nombre de la propiedad.
+                        </para>                    
+                    </callout>                   
+                    <callout arearefs="manytoone2">
+                        <para>
+                            <literal>column</literal> (opcional): El nombre de la columna clave for&#x00e1;nea.
+                            Tambi&#x00e9;n puede ser especificado por uno o varios elementos anidados
+                            <literal>&lt;column&gt;</literal>.
+                        </para>
+                    </callout>
+                    <callout arearefs="manytoone3">
+                        <para>
+                            <literal>class</literal> (opcional - por defecto al tipo de la propiedad
+                            determinado por reflecci&#x00f3;n): El nombre de la clase asociada.
+                        </para>
+                    </callout>
+                    <callout arearefs="manytoone4">
+                        <para>
+                            <literal>cascade</literal> (opcional): Especifica qu&#x00e9; operaciones deben
+                            ir en cascada desde el objeto padre al objeto asociado
+                        </para>                    
+                    </callout>
+                    <callout arearefs="manytoone5">
+                        <para>
+                            <literal>fetch</literal> (opcional - por defecto a 1<literal>select</literal>): 
+                            Escoge entre recuperaci&#x00f3;n outer-join o por selecci&#x00f3;n secuencial.
+                        </para>                    
+                    </callout>
+                    <callout arearefs="manytoone6-7">
+                        <para>
+                            <literal>update, insert</literal> (opcional - por defecto a <literal>true</literal>)
+                            especifica que las columnas mapeadas deben ser inclu&#x00ed;das en las sentencias SQL
+                            <literal>UPDATE</literal> y/o <literal>INSERT</literal>. Establecer ambas a
+                            <literal>false</literal> permite una asociaci&#x00f3;n puramente "derivada" cuyo
+                            valor es inicializado desde alguna otra propiedad que mapea a las misma columna (o columnas),
+                            o por un disparador, o por otra aplicaci&#x00f3;n.
+                        </para>                    
+                    </callout>
+                    <callout arearefs="manytoone8">
+                        <para>
+                            <literal>property-ref</literal>: (opcional) El nombre de la propiedad de la clase
+                            asociada que est&#x00e1; unida a la clave for&#x00e1;nea. Si no se especifica, se usa
+                            la clave primaria de la clase asociada.
+                        </para>                
+                    </callout>                   
+                   <callout arearefs="manytoone9">
+                        <para>
+                            <literal>access</literal> (opcional - por defecto a <literal>property</literal>): La
+                            estrategia que Hibernate debe usar para acceder al valor de la propiedad.
+                        </para>
+                    </callout>
+                    <callout arearefs="manytoone10">
+                        <para>
+                            <literal>unique</literal> (opcional): Habilita la generaci&#x00f3;n DDL de una
+                            restricci&#x00f3;n de unicidad para la columna de clave for&#x00e1;nea. Adem&#x00e1;s,
+                            permite que &#x00e9;sta sea el objetivo de una <literal>property-ref</literal>.
+                            Esto hace efectivamente la multiplicidad de la asociaci&#x00f3;n uno a uno.
+                        </para>
+                    </callout>
+                    <callout arearefs="manytoone11">
+                        <para>
+                            <literal>not-null</literal> (opcional): Habilita la generaci&#x00f3;n DDL de una
+                            restricci&#x00f3;n de nulabilidad para las columnas de clave for&#x00e1;nea. 
+                        </para>
+                    </callout>
+                    <callout arearefs="manytoone12">
+                        <para>
+                            <literal>optimistic-lock</literal> (opcional - por defecto a <literal>true</literal>): 
+                            Especifica que las actualizaciones a esta propiedad requieran o no la obtenci&#x00f3;n
+                            del bloqueo optimista. En otras palabras, determina si debe darse un incremento de versi&#x00f3;n
+                            cuando esta propiedad est&#x00e9; desactualizada.
+                        </para>
+                    </callout>
+                    <callout arearefs="manytoone13">
+                        <para>
+                            <literal>lazy</literal> (opcional - por defecto a <literal>proxy</literal>):
+                            Por defecto, las asociaciones de punto &#x00fa;nico van con proxies.
+                            <literal>lazy="true"</literal> especifica que esta propiedad debe ser
+                            tra&#x00ed;da perezosamente cuando la variable de instancia sea accedida por primera
+                            vez (requiere instrumentaci&#x00f3;n del bytecode en tiempo de compilaci&#x00f3;n).
+                            <literal>lazy="false"</literal> especifica que la asociaci&#x00f3;n siempre ser&#x00e1;
+                            recuperada tempranamente.
+                        </para>
+                    </callout>
+                    <callout arearefs="manytoone14">
+                        <para>
+                            <literal>not-found</literal> (opcional - por defecto a <literal>exception</literal>): 
+                            Especifica c&#x00f3;mo deben manejarse las claves for&#x00e1;neas que referencien
+                            filas inexistentes: <literal>ignore</literal> tratar&#x00e1; una fila perdida como
+                            una asociaci&#x00f3;n nula.
+                        </para>
+                    </callout>
+                    <callout arearefs="manytoone15">
+                        <para>
+                            <literal>entity-name</literal> (opcional): El nombre de entidad de la clase
+                            asociada.
+                        </para>
+                    </callout>
+                    <callout arearefs="manytoone16">
+                        <para>
+                            <literal>formula</literal> (opcional): una expresi&#x00f3;n SQL que define el valor
+                            para una clave for&#x00e1;nea <emphasis>computada</emphasis>.
+                        </para>
+                    </callout>
+
+                </calloutlist>
+            </programlistingco>
+
+            <para>
+                Establecer el valor del atributo <literal>cascade</literal> a cualquier valor
+                significativo distinto de <literal>none</literal> propagar&#x00e1; ciertas
+                operaciones al objeto asociado. Los valores significativos son los nombres de las
+                operaciones b&#x00e1;sicas de Hibernate, <literal>persist, merge, delete, save-update,
+                evict, replicate, lock, refresh</literal>, as&#x00ed; como los valores especiales
+                <literal>delete-orphan</literal> y <literal>all</literal> y combinaciones de operaciones
+                separadas por coma, por ejemplo, <literal>cascade="persist,merge,evict"</literal> o
+                <literal>cascade="all,delete-orphan"</literal>. Para una explicaci&#x00f3;n completa,
+                ver <xref linkend="objectstate-transitive"/>.
+            </para>
+            
+            <para>
+                Una declaraci&#x00f3;n t&#x00ed;pica <literal>muchos-a-uno</literal> se parece a esto:
+            </para>
+
+            <programlisting><![CDATA[<many-to-one name="product" class="Product" column="PRODUCT_ID"/>]]></programlisting>
+            
+            <para>
+                El atributo <literal>property-ref</literal> debe ser usado solamente para el mapeo
+                de datos heredados donde una clave for&#x00e1;nea referencia una clave &#x00fa;nica de
+                la tabla asociada, distinta de la clave primaria. Este es un modelo relacional feo.
+                Por ejemplo, sup&#x00f3;n que la clase <literal>Product</literal> tuviera un n&#x00fa;mero
+                &#x00fa;nico serial que no es la clave primaria. (El atributo <literal>unique</literal>
+                controla la generaci&#x00f3;n de DDL con la herramienta SchemaExport.)
+            </para>
+            
+            <programlisting><![CDATA[<property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>]]></programlisting>
+            
+            <para>
+                Entonces el mapeo para <literal>OrderItem</literal> deber&#x00ed;a usar:
+            </para>
+            
+            <programlisting><![CDATA[<many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>]]></programlisting>
+            
+            <para>
+                Sin embargo, esto no esta ciertamente alentado.
+            </para>
+            
+            <para>
+                Si la clave &#x00fa;nica referenciada abarca m&#x00fa;ltiples propiedades de la entidad asociada,
+                debes mapear las propiedades dentro de un elemento <literal>&lt;properties&gt;</literal>.
+            </para>
+            
+        </sect2>
+
+        <sect2 id="mapping-declaration-onetoone" revision="2">
+            <title>one-to-one</title>
+
+            <para>
+                Una asociaci&#x00f3;n uno-a-uno a otra clase persistente se declara usando
+                un elemento <literal>one-to-one</literal>.
+            </para>
+            
+            <programlistingco>
+                <areaspec>
+                    <area id="onetoone1" coords="2 70"/>
+                    <area id="onetoone2" coords="3 70"/>
+                    <area id="onetoone3" coords="4 70"/>
+                    <area id="onetoone4" coords="5 70"/>
+                    <area id="onetoone5" coords="6 70"/>
+                    <area id="onetoone6" coords="7 70"/>
+                    <area id="onetoone7" coords="8 70"/>
+                    <area id="onetoone8" coords="9 70"/>
+                    <area id="onetoone9" coords="10 70"/>
+                    <area id="onetoone10" coords="11 70"/>
+                </areaspec>
+                <programlisting><![CDATA[<one-to-one
+        name="propertyName"
+        class="ClassName"
+        cascade="cascade_style"
+        constrained="true|false"
+        fetch="join|select"
+        property-ref="propertyNameFromAssociatedClass"
+        access="field|property|ClassName"
+        formula="cualquier expresi&#x00f3;n SQL"
+        lazy="true|proxy|false"
+        entity-name="EntityName"
+        node="element-name|@attribute-name|element/@attribute|."
+        embed-xml="true|false"
+        foreign-key="foreign_key_name"
+/>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="onetoone1">
+                        <para>
+                            <literal>name</literal>: El nombre de la propiedad.
+                        </para>                
+                    </callout>                   
+                    <callout arearefs="onetoone2">
+                        <para>
+                            <literal>class</literal> (opcional - por defecto al tipo de la propiedad
+                            determinado por reflecci&#x00f3;n): El nombre de la clase asociada.
+                        </para>                   
+                    </callout>
+                    <callout arearefs="onetoone3">
+                        <para>
+                            <literal>cascade</literal> (opcional) especifica qu&#x00e9; operaciones deben
+                            ir en cascada desde el objeto padre al objeto asociado.
+                        </para>
+                    </callout>
+                    <callout arearefs="onetoone4">
+                        <para>
+                            <literal>constrained</literal> (opcional) especifica que una restricci&#x00f3;n
+                            de clave for&#x00e1;nea de la tabla mapeada referencia a la tabla de la clase
+                            asociada. Esta opci&#x00f3;n afecta el orden en que van en cascada
+                            <literal>save()</literal> y <literal>delete()</literal>, y determina cu&#x00e1;ndo
+                            la asociaci&#x00f3;n pueden ser virtualizados por proxies (es tambi&#x00e9;n usado por
+                            la herramienta de exportaci&#x00f3;n de esquemas).
+                        </para>                  
+                    </callout>
+                    <callout arearefs="onetoone5">
+                        <para>
+                            <literal>fetch</literal> (opcional - por defecto <literal>select</literal>): 
+                            Elige entre recuperaci&#x00f3;n outer-join o recuperaci&#x00f3;n por consulta secuencial.
+                        </para>              
+                    </callout>
+                    <callout arearefs="onetoone6">
+                        <para>
+                            <literal>property-ref</literal>: (opcional) El nombre de una propiedad de la clase
+                            asociada que est&#x00e9; unida a la clave primaria de esta clase. Si no se especifica,
+                            se usa la clave primaria de la clase asociada.
+                        </para>                
+                    </callout>                   
+                    <callout arearefs="onetoone7">
+                        <para>
+                            <literal>access</literal> (opcional - por defecto a <literal>property</literal>): La
+                            estrategia que Hibernate debe usar para acceder al valor de la propiedad.
+                        </para>
+                    </callout>
+                    <callout arearefs="onetoone8">
+                        <para>
+                            <literal>formula</literal> (opcional): Casi todas las asociaciones uno-a-uno mapean
+                            a la clave primaria de la entidad propietaria. En el raro caso en que este no sea el caso,
+                            puedes especificar alguna otra columna, o columnas, o expresi&#x00f3;n para unir usando una
+                            f&#x00f3;rmula SQL. (Para un ejemplo ver <literal>org.hibernate.test.onetooneformula</literal>).
+                        </para>
+                    </callout>
+                    <callout arearefs="onetoone9">
+                        <para>
+                            <literal>lazy</literal> (opcional - por defecto a <literal>proxy</literal>):
+                            Por defecto, las asociaciones de punto &#x00fa;nico van con proxies.
+                            <literal>lazy="true"</literal> especifica que esta propiedad debe ser
+                            tra&#x00ed;da perezosamente cuando la variable de instancia sea accedida por primera
+                            vez (requiere instrumentaci&#x00f3;n del bytecode en tiempo de compilaci&#x00f3;n).
+                            <literal>lazy="false"</literal> especifica que la asociaci&#x00f3;n siempre ser&#x00e1;
+                            recuperada tempranamente. <emphasis>Observa que si <literal>constrained="false"</literal>,
+                            la aplicaci&#x00f3;n de proxies es imposible e Hibernate traer&#x00e1; temprano la
+                            asociaci&#x00f3;n!</emphasis>
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+        
+            <para>
+                Hay dos variedades de asociaciones uno-a-uno:
+            </para>
+            <itemizedlist>
+            <listitem><para>
+                asociaciones de clave primaria
+            </para></listitem>
+            <listitem><para>
+                asociaciones de clave for&#x00e1;neas &#x00fa;nica
+            </para></listitem>
+            </itemizedlist>
+            
+            <para>
+                Las asociaciones de clave primaria no necesitan una columna de tabla extra; si dos filas
+                est&#x00e1;n relacionadas por la asociaci&#x00f3;n entonces las dos filas de tablas comparten
+                el mismo valor de clave primaria. Por lo tanto, si quieres que dos objetos est&#x00e9;n relacionados
+                por una asociaci&#x00f3;n de clave primaria, debes asegurarte que se les asigne el mismo valor de
+                identificador!
+            </para>
+            
+            <para>
+                Para una asociaci&#x00f3;n de clave primaria, a&#x00f1;ade los siguientes mapeos a
+                <literal>Employee</literal> y <literal>Person</literal>, respectivamente.
+            </para>
+
+            <programlisting><![CDATA[<one-to-one name="person" class="Person"/>]]></programlisting>
+            <programlisting><![CDATA[<one-to-one name="employee" class="Employee" constrained="true"/>]]></programlisting>
+
+            <para>
+                Ahora debemos asegurarnos que las claves primarias de las filas relacionadas en las tablas
+                PERSON y EMPLOYEE sean iguales. Usamos una estrategia especial de generaci&#x00f3;n de identificador
+                de Hibernate llamada <literal>foreign</literal>:
+            </para>
+
+            <programlisting><![CDATA[<class name="person" table="PERSON">
+    <id name="id" column="PERSON_ID">
+        <generator class="foreign">
+            <param name="property">employee</param>
+        </generator>
+    </id>
+    ...
+    <one-to-one name="employee"
+        class="Employee"
+        constrained="true"/>
+</class>]]></programlisting>
+
+            <para>
+                A una instancia reci&#x00e9;n salvada de <literal>Person</literal> se le asigna entonces
+                el mismo valor de clave primaria con que la instancia  <literal>Employee</literal>
+                referida por la propiedad <literal>employee</literal> de esta <literal>Person</literal>.
+            </para>
+
+            <para>
+                Alternativamente, una clave for&#x00e1;nea con una restricci&#x00f3;n de unicidad, desde
+                <literal>Employee</literal> a <literal>Person</literal>, puede ser expresada como:
+            </para>
+            
+            <programlisting><![CDATA[<many-to-one name="person" class="Person" column="PERSON_ID" unique="true"/>]]></programlisting>
+            
+            <para>
+                Y esta asociaci&#x00f3;n puede hacerse bidireccional agregando lo siguiente al mapeo de
+                <literal>Person</literal> :
+            </para>
+            
+           <programlisting><![CDATA[<one-to-one name="employee" class="Employee" property-ref="person"/>]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="mapping-declaration-naturalid">
+            <title>natural-id</title>
+
+            <programlisting><![CDATA[<natural-id mutable="true|false"/>
+        <property ... />
+        <many-to-one ... />
+        ......
+</natural-id>]]></programlisting>
+
+            <para>
+                Aunque recomendamos el uso de claves delegadas como claves primarias, todav&#x00ed;a debes
+                intentar identificar claves naturales para todas las entidades. Una clave natural es una
+                propiedad o combinaci&#x00f3;n de propiedades que es &#x00fa;nica y no nula. Si adem&#x00e1;s
+                es inmutable, mejor a&#x00fa;n. Mapea las propiedades de la clave natural dentro del elemento
+                <literal>&lt;natural-id&gt;</literal>. Hibernate generar&#x00e1; las restricciones de clave
+                &#x00fa;nica y nulabilidad necesarias, y tu mapeo ser&#x00e1; m&#x00e1;s auto-documentado.
+            </para>
+            
+            <para>
+                Recomendamos fuertemente que implementes <literal>equals()</literal> y
+                <literal>hashCode()</literal> para comparar las propiedades de clave natural
+                de la entidad.
+            </para>
+
+            <para>
+                Este mapeo no est&#x00e1; concebido para usar con entidades con claves
+                primarias naturales.
+            </para>
+
+            <itemizedlist spacing="compact">
+                <listitem>
+                    <para>
+                        <literal>mutable</literal> (opcional, por defecto a <literal>false</literal>): 
+                        Por defecto, se asume que las propiedades de identificadores naturales son
+                        inmutables (constantes). 
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </sect2>
+
+
+
+        <sect2 id="mapping-declaration-component" revision="2">
+            <title>component, dynamic-component</title>
+
+            <para>
+                El elemento <literal>&lt;component&gt;</literal> mapea propiedades de un objeto
+                hijo a columnas de la tabla de la clase padre. Los componentes pueden a su vez
+                declarar sus propias propiedades, componentes o colecciones. Ver debajo "Componentes".
+            </para>
+
+            <programlistingco>
+                <areaspec>
+                    <area id="component1" coords="2 45"/>
+                    <area id="component2" coords="3 45"/>
+                    <area id="component3" coords="4 45"/>
+                    <area id="component4" coords="5 45"/>
+                    <area id="component5" coords="6 45"/>
+                    <area id="component6" coords="7 45"/>
+                    <area id="component7" coords="8 45"/>
+                    <area id="component8" coords="9 45"/>
+                </areaspec>            
+                <programlisting><![CDATA[<component 
+        name="propertyName" 
+        class="className"
+        insert="true|false"
+        update="true|false"
+        access="field|property|ClassName"
+        lazy="true|false"
+        optimistic-lock="true|false"
+        unique="true|false"
+        node="element-name|."
+>
+        
+        <property ...../>
+        <many-to-one .... />
+        ........
+</component>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="component1">
+                        <para>
+                            <literal>name</literal>: El nombre de la propiedad.
+                        </para>               
+                    </callout>                   
+                    <callout arearefs="component2">
+                        <para>
+                            <literal>class</literal> (opcional - por defecto al tipo de la propiedad
+                            determinado por reflecci&#x00f3;n): El nombre de la clase del componente (hijo).
+                        </para>                 
+                    </callout>
+                    <callout arearefs="component3">
+                        <para>
+                            <literal>insert</literal>: Aparecen las columnas mapeadas en
+                            <literal>INSERT</literal>s SQL?
+                        </para>               
+                    </callout>                   
+                    <callout arearefs="component4">
+                        <para>
+                            <literal>update</literal>: Aparecen las columnas mapeadas en
+                            <literal>UPDATE</literal>s SQL?
+                        </para>               
+                    </callout>                   
+                    <callout arearefs="component5">
+                        <para>
+                            <literal>access</literal> (opcional - por defecto a <literal>property</literal>): La
+                            estrategia que Hibernate debe usar para acceder al valor de la propiedad.
+                        </para>
+                    </callout>
+                   <callout arearefs="component6">
+                        <para>
+                            <literal>lazy</literal> (opcional - por defecto a <literal>false</literal>): Especifica
+                            que este componente debe ser recuperado perezosamente cuando la variable de instancia
+                            sea accedida por primera vez (requiere instrumentaci&#x00f3;n de bytecode en tiempo de
+                            compilaci&#x00f3;n).
+                        </para>
+                    </callout>
+                    <callout arearefs="component7">
+                            <para>
+                                <literal>optimistic-lock</literal> (opcional - por defecto a <literal>true</literal>):
+                                Especifica si las actualizaciones de este componente requieren o no la
+                                adquisici&#x00f3;n de un bloqueo optimista. En otras palabras, determina si
+                                debe ocurrir un incremento de versi&#x00f3;n cuando esta propiedad est&#x00e1;
+                                desactualizada.
+                            </para>
+                    </callout>
+                    <callout arearefs="component8">
+                            <para>
+                                <literal>unique</literal> (opcional - por defecto a <literal>false</literal>):
+                                Especifica que existe una restricci&#x00f3;n de unicidad sobre todas las
+                                columnas mapeadas del componente.
+                            </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+
+            <para>
+                Las etiquetas hijas <literal>&lt;property&gt;</literal> mapean propiedades de la
+                clase hija columnas de la tabla.
+            </para>
+
+            <para>
+                El elemento <literal>&lt;component&gt;</literal> permite un subelemento
+                <literal>&lt;parent&gt;</literal> que mapea una propiedad de la clase del componente
+                como una referencia de regreso a la entidad contenedora.
+            </para>
+
+            <para>
+                El elemento <literal>&lt;dynamic-component&gt;</literal> permite que un 
+                <literal>Map</literal> sea mapeado como un componente, donde los nombres de
+                las propiedades se corresponden a las claves del mapa, ver <xref linkend="components-dynamic"/>.
+            </para>
+            
+        </sect2>
+
+        <sect2 id="mapping-declaration-properties" revision="2">
+            <title>properties</title>
+
+            <para>
+                El elemento <literal>&lt;properties&gt;</literal> permite la definici&#x00f3;n de
+                un grupo de propiedades l&#x00f3;gico con nombre de una clase. El uso m&#x00e1;s
+                importante de la contrucci&#x00f3;n es que permite que una combinaci&#x00f3;n
+                de propiedades sea objetivo de una <literal>property-ref</literal>. Es tambi&#x00e9;n
+                una forma conveniente de definir una restricci&#x00f3;n de unicidad multicolumna.
+            </para>
+
+            <programlistingco>
+                <areaspec>
+                    <area id="properties1" coords="2 45"/>
+                    <area id="properties2" coords="3 45"/>
+                    <area id="properties3" coords="4 45"/>
+                    <area id="properties4" coords="5 45"/>
+                    <area id="properties5" coords="6 45"/>
+                </areaspec>            
+                <programlisting><![CDATA[<properties 
+        name="logicalName" 
+        insert="true|false"
+        update="true|false"
+        optimistic-lock="true|false"
+        unique="true|false"
+>
+        
+        <property ...../>
+        <many-to-one .... />
+        ........
+</properties>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="properties1">
+                        <para>
+                            <literal>name</literal>: El nombre l&#x00f3;gico del agrupamiento -
+                            <emphasis>no</emphasis> un nombre de propiedad real.
+                        </para>               
+                    </callout>                   
+                    <callout arearefs="properties2">
+                        <para>
+                            <literal>insert</literal>: Aparecen las columnas mapeadas en 
+                            <literal>INSERT</literal>s SQL?
+                        </para>               
+                    </callout>                   
+                    <callout arearefs="properties3">
+                        <para>
+                            <literal>update</literal>: Aparecen las columnas mapeadas en 
+                            <literal>UPDATE</literal>s SQL?
+                        </para>               
+                    </callout>                   
+                    <callout arearefs="properties4">
+                            <para>
+                                <literal>optimistic-lock</literal> (opcional - por defecto a <literal>true</literal>):
+                                Especifica si las actualizaciones de estas propiedades requieren o no de la
+                                adquisici&#x00f3;n de un bloqueo optimista. En otras palabras, determina si
+                                debe ocurrir un incremento de versi&#x00f3;n cuando estas propiedades est&#x00e1;n
+                                desactualizadas.
+                            </para>
+                    </callout>
+                    <callout arearefs="properties5">
+                            <para>
+                                <literal>unique</literal> (opcional - por defecto a <literal>false</literal>):
+                                Especifica que existe una restricci&#x00f3;n de unicidad sobre todas las
+                                columnas mapeadas del componente.
+                            </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+            
+            <para>
+                Por ejemplo, si tenemos el siguiente mapeo de <literal>&lt;properties&gt;</literal>:
+            </para>
+            
+            <programlisting><![CDATA[<class name="Person">
+    <id name="personNumber"/>
+    ...
+    <properties name="name" 
+            unique="true" update="false">
+        <property name="firstName"/>
+        <property name="initial"/>
+        <property name="lastName"/>
+    </properties>
+</class>]]></programlisting>
+
+            <para>
+                Entonces puede que tengamos alguna asociaci&#x00f3;n de datos heredados que se refiera
+                a esta clave &#x00fa;nica de la tabla de <literal>Person</literal>, en vez de la clave
+                primaria:
+            </para>
+
+            <programlisting><![CDATA[<many-to-one name="person" 
+         class="Person" property-ref="name">
+    <column name="firstName"/>
+    <column name="initial"/>
+    <column name="lastName"/>
+</many-to-one>]]></programlisting>
+            
+            <para>
+                No recomendamos el uso de este tipo de cosas fuera del contexto del mapeo de
+                datos heredados.
+            </para>
+            
+        </sect2>
+
+        <sect2 id="mapping-declaration-subclass" revision="3">
+            <title>subclass</title>
+
+            <para>
+                Finalmente, la persistencia polim&#x00f3;rfica requiere la declaraci&#x00f3;n
+                de la clase persistente ra&#x00ed;z. Para la estrategia de mapeo
+                tabla-por-jerarqu&#x00ed;a-de-clases, se usa la declaraci&#x00f3;n de
+                <literal>&lt;subclass&gt;</literal>.
+            </para>
+            
+            <programlistingco>
+                <areaspec>
+                    <area id="subclass1" coords="2 55"/>
+                    <area id="subclass2" coords="3 55"/>
+                    <area id="subclass3" coords="4 55"/>
+                    <area id="subclass4" coords="5 55"/>
+                </areaspec>
+                <programlisting><![CDATA[<subclass
+        name="ClassName"
+        discriminator-value="discriminator_value"
+        proxy="ProxyInterface"
+        lazy="true|false"
+        dynamic-update="true|false"
+        dynamic-insert="true|false"
+        entity-name="EntityName"
+        node="element-name">
+
+        <property .... />
+        .....
+</subclass>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="subclass1">
+                        <para>
+                            <literal>name</literal>: El nombre de clase cualificado completamente
+                            de la subclase.
+                        </para>              
+                    </callout>                   
+                    <callout arearefs="subclass2">
+                        <para>
+                            <literal>discriminator-value</literal> (opcional - por defecto al nombre de la clase):
+                            Un valor que distingue a subclases individuales.
+                        </para>               
+                    </callout>
+                    <callout arearefs="subclass3">
+                        <para>
+                            <literal>proxy</literal> (opcional): Especifica una clase o interface a usar para
+                            proxies de inicializaci&#x00f3;n perezosa.
+                        </para>               
+                    </callout>
+                    <callout arearefs="subclass4">
+                        <para>
+                            <literal>lazy</literal> (opcional, por defecto a <literal>true</literal>):
+                            Establecer <literal>lazy="false"</literal> deshabilita el uso de recuperaci&#x00f3;n
+                            perezosa.
+                        </para>
+                    </callout>    
+                </calloutlist>
+            </programlistingco>
+
+            <para>
+                Cada subclase debe declarar sus propias propiedades persistentes y subclases.
+                Se asume que las propiedades <literal>&lt;version&gt;</literal> y <literal>&lt;id&gt;</literal>
+                son heredadas de la clase ra&#x00ed;z. Cada subclase en una jerarqu&#x00ed;a debe
+                definir un <literal>discriminator-value</literal> &#x00fa;nico. Si no se especifica ninguno,
+                se usa el nombre completamente cualificado de clase Java.
+            </para>
+            
+       <para>
+            Es posible definir mapeos <literal>subclass</literal>, <literal>union-subclass</literal>,
+            y <literal>joined-subclass</literal> en documentos de mapeo separados, directamente debajo
+            de <literal>hibernate-mapping</literal>. Esto te permite extender una jerarqu&#x00ed;a de clases
+            con s&#x00f3;lo agregar un nuevo fichero de mapeo. Debes especificar un atributo
+            <literal>extends</literal> en el mapeo de la subclase, mencionando una superclase previamente mapeada.
+            Nota: Previamente esta funcionalidad hac&#x00ed;a importante el orden de los documentos de mapeo.
+            Desde Hibernate3, el orden de los ficheros de mapeo no importa cuando se usa la palabra reservada
+            extends. El orden dentro de un mismo fichero de mapeo todav&#x00ed;a necesita ser definido como
+            superclases antes de subclases.
+        </para>
+    
+        <programlisting><![CDATA[
+<hibernate-mapping>
+    <subclass name="DomesticCat" extends="Cat" discriminator-value="D">
+         <property name="name" type="string"/>
+    </subclass>
+</hibernate-mapping>]]></programlisting>
+
+            <para>
+                Para informaci&#x00f3;n acerca de mapeos de herencia, ver <xref linkend="inheritance"/>.
+            </para>
+
+        </sect2>
+
+         <sect2 id="mapping-declaration-joinedsubclass" revision="3">
+            <title>joined-subclass</title>
+
+            <para>
+                Alternativamente, cada subclase puede ser mapeada a su propia tabla
+                (estrategia de mapeo tabla-por-subclase). El estado heredado se recupera
+                uniendo con la tabla de la superclase.
+                Usamos el elemento <literal>&lt;joined-subclass&gt;</literal>.
+            </para>
+
+            <programlistingco>
+                <areaspec>
+                    <area id="joinedsubclass1" coords="2 45"/>
+                    <area id="joinedsubclass2" coords="3 45"/>
+                    <area id="joinedsubclass3" coords="4 45"/>
+                    <area id="joinedsubclass4" coords="5 45"/>
+                </areaspec>
+                <programlisting><![CDATA[<joined-subclass
+        name="ClassName"
+        table="tablename"
+        proxy="ProxyInterface"
+        lazy="true|false"
+        dynamic-update="true|false"
+        dynamic-insert="true|false"
+        schema="schema"
+        catalog="catalog"
+        extends="SuperclassName"
+        persister="ClassName"
+        subselect="SQL expression"
+        entity-name="EntityName"
+        node="element-name">
+
+        <key .... >
+
+        <property .... />
+        .....
+</joined-subclass>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="joinedsubclass1">
+                        <para>
+                            <literal>name</literal>: El nombre de clase completamente cualificado de
+                            la subclase.
+                        </para>            
+                    </callout>                   
+                    <callout arearefs="joinedsubclass2">
+                        <para>
+                            <literal>table</literal>: El nombre de tabla de la subclase.
+                        </para>            
+                    </callout>                   
+                    <callout arearefs="joinedsubclass3">
+                        <para>
+                            <literal>proxy</literal> (opcional): Especifica una clase o interface a
+                            usar para proxies de inicializac&#x00f3;n perezosa.
+                        </para>              
+                    </callout>
+                    <callout arearefs="joinedsubclass4">
+                        <para>
+                             <literal>lazy</literal> (opcional, por defecto a <literal>true</literal>):
+                            Establecer <literal>lazy="false"</literal> deshabilita el uso de recuperaci&#x00f3;n
+                            perezosa.
+                         </para>
+                    </callout>    
+                </calloutlist>
+            </programlistingco>
+
+            <para>
+                No se requiere de una columna discriminadora para esta estrategia de mapeo. Cada subclase debe,
+                sin embargo, declarar una columna de tabla que tenga el identificador del objeto usando el
+                elemento <literal>&lt;key&gt;</literal>. El mapeo del comienzo del cap&#x00ed;tulo
+                deber&#x00ed;a ser reescrito como:
+            </para>
+            
+        <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+        "-//Hibernate/Hibernate Mapping DTD//EN"
+        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+        <class name="Cat" table="CATS">
+                <id name="id" column="uid" type="long">
+                        <generator class="hilo"/>
+                </id>
+                <property name="birthdate" type="date"/>
+                <property name="color" not-null="true"/>
+                <property name="sex" not-null="true"/>
+                <property name="weight"/>
+                <many-to-one name="mate"/>
+                <set name="kittens">
+                        <key column="MOTHER"/>
+                        <one-to-many class="Cat"/>
+                </set>
+                <joined-subclass name="DomesticCat" table="DOMESTIC_CATS">
+                    <key column="CAT"/>
+                    <property name="name" type="string"/>
+                </joined-subclass>
+        </class>
+
+        <class name="eg.Dog">
+                <!-- mapping for Dog could go here -->
+        </class>
+
+</hibernate-mapping>]]></programlisting>
+
+             <para>
+                 Para informaci&#x00f3;n acerca de mapeos de herencia, ver <xref linkend="inheritance"/>.
+             </para>
+
+        </sect2>
+
+        <sect2 id="mapping-declaration-unionsubclass" revision="2">
+           <title>union-subclass</title>
+
+           <para>
+               Una tercera opci&#x00f3;n es mapear s&#x00f3;lo las clases concretas de una
+               jerarqu&#x00ed;a de clases a tablas, (la estrategia tabla-por-clase-concreta)
+               donde cada tabla define todo el estado persistente de la clase, incluyendo el
+               estado heredado. En Hibernate, no es absolutamente necesario mapear dichas
+               jerarqu&#x00ed;as de herencia. Puedes simplemente mapear cada clase con una
+               declaraci&#x00f3;n <literal>&lt;class&gt;</literal> separada. Sin embargo,
+               si deseas usar asociaciones polim&#x00f3;rficas (por ejemplo, una asociaci&#x00f3;n
+               a la superclase de tu jerarqu&#x00ed;a), debes usar el mapeo
+               <literal>&lt;union-subclass&gt;</literal>.
+           </para>
+
+            <programlistingco>
+                <areaspec>
+                    <area id="unionsubclass1" coords="2 45"/>
+                    <area id="unionsubclass2" coords="3 45"/>
+                    <area id="unionsubclass3" coords="4 45"/>
+                    <area id="unionsubclass4" coords="5 45"/>
+                </areaspec>
+                <programlisting><![CDATA[<union-subclass
+        name="ClassName"
+        table="tablename"
+        proxy="ProxyInterface"
+        lazy="true|false"
+        dynamic-update="true|false"
+        dynamic-insert="true|false"
+        schema="schema"
+        catalog="catalog"
+        extends="SuperclassName"
+        abstract="true|false"
+        persister="ClassName"
+        subselect="SQL expression"
+        entity-name="EntityName"
+        node="element-name">
+
+        <property .... />
+        .....
+</union-subclass>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="unionsubclass1">
+                        <para>
+                            <literal>name</literal>: El nombre de clase completamente cualificado de la subclase.
+                        </para>            
+                    </callout>                   
+                    <callout arearefs="unionsubclass2">
+                        <para>
+                            <literal>table</literal>: El nombre de tabla de la subclase.
+                        </para>            
+                    </callout>                   
+                    <callout arearefs="unionsubclass3">
+                        <para>
+                            <literal>proxy</literal> (optional): Especifica una clase o interface a
+                            usar para proxies de inicializac&#x00f3;n perezosa.
+                        </para>              
+                    </callout>
+                    <callout arearefs="unionsubclass4">
+                        <para>
+                            <literal>lazy</literal> (opcional, por defecto a <literal>true</literal>):
+                            Establecer <literal>lazy="false"</literal> deshabilita el uso de recuperaci&#x00f3;n
+                            perezosa.
+                         </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+
+            <para>
+                No se requiere columna o columna clave discriminadora para esta estrategia de mapeo.
+            </para>
+
+            <para>
+                Para informaci&#x00f3;n acerca de mapeos de herencia, ver <xref linkend="inheritance"/>.
+            </para>
+
+        </sect2>
+
+   	<sect2 id="mapping-declaration-join" revision="3">
+            <title>join</title>
+
+            <para>
+                Usando el elemento <literal>&lt;join&gt;</literal>, es posible mapear
+                propiedades de una clase a varias tablas.
+            </para>
+
+            <programlistingco>
+                <areaspec>
+                    <area id="join1" coords="2 50"/>
+                    <area id="join2" coords="3 50"/>
+                    <area id="join3" coords="4 50"/>
+                    <area id="join4" coords="5 50"/>
+                    <area id="join5" coords="6 50"/>
+                    <area id="join6" coords="7 50"/>
+                </areaspec>
+                <programlisting><![CDATA[<join
+        table="tablename"
+        schema="owner"
+        catalog="catalog"
+        fetch="join|select"
+        inverse="true|false"
+        optional="true|false">
+        
+        <key ... />
+        
+        <property ... />
+        ...
+</join>]]></programlisting>
+
+                <calloutlist>
+                    <callout arearefs="join1">
+                        <para>
+                            <literal>table</literal>: El nombre de la clase unida.
+                        </para>
+                    </callout>
+                    <callout arearefs="join2">
+                        <para>
+                            <literal>schema</literal> (opcional): Sobrescribe el nombre de esquema
+                            especificado por el elemento ra&#x00ed;z <literal>&lt;hibernate-mapping&gt;</literal>.
+                        </para>
+                    </callout>
+                    <callout arearefs="join3">
+                        <para>
+                            <literal>catalog</literal> (opcional): Sobrescribe el nombre de cat&#x00e1;logo
+                            especificado por el elemento ra&#x00ed;z <literal>&lt;hibernate-mapping&gt;</literal>.
+                        </para>
+                    </callout>
+                    <callout arearefs="join4">
+                        <para>
+                            <literal>fetch</literal> (opcional - por defecto a <literal>join</literal>):
+                            Si se establece a <literal>join</literal>, por defecto, Hibernate usar&#x00e1;
+                            una uni&#x00f3;n interior (inner join) para recuperar un <literal>&lt;join&gt;</literal>
+                            definido por una clase o sus superclases y una uni&#x00f3;n externa (outer join)
+                            para un <literal>&lt;join&gt;</literal> definido por una subclase.
+                            Si se establece a <literal>select</literal>, entonces Hibernate usar&#x00e1; una
+                            select secuencial para un <literal>&lt;join&gt;</literal> definido en una subclase,
+                            que ser&#x00e1; publicada s&#x00f3;lo si una fila resulta representar una instancia
+                            de la subclase. Las uniones interiores todav&#x00ed;a ser&#x00e1;n usados para
+                            recuperar un <literal>&lt;join&gt;</literal> definido por la clase y sus superclases.
+                        </para>
+                    </callout>
+                    <callout arearefs="join5">
+                        <para>
+                            <literal>inverse</literal> (opcional - por defecto a <literal>false</literal>):
+                            De habilitarse, Hibernate no intentar&#x00e1; insertar o actualizar las propiedades
+                            definidas por esta uni&#x00f3;n.
+                        </para>
+                    </callout>
+                    <callout arearefs="join6">
+                        <para>
+                            <literal>optional</literal> (opcional - por defecto a <literal>false</literal>):
+                            De habilitarse, Hibernate insertar&#x00e1; una fila s&#x00f3;lo si las propiedades
+                            definidas por esta uni&#x00f3;n son no nulas y siempre usar&#x00e1; una uni&#x00f3;n
+                            externa para recuperar las propiedades.
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+
+            <para>
+                Por ejemplo, la informaci&#x00f3;n domiciliaria de una persona puede ser mapeada
+                a una tabla separada (preservando a la vez la sem&#x00e1;ntica de tipo de valor para
+                todas las propiedades):
+            </para>
+
+            <programlisting><![CDATA[<class name="Person"
+    table="PERSON">
+
+    <id name="id" column="PERSON_ID">...</id>
+
+    <join table="ADDRESS">
+        <key column="ADDRESS_ID"/>
+        <property name="address"/>
+        <property name="zip"/>
+        <property name="country"/>
+    </join>
+    ...]]></programlisting>
+
+            <para>
+                Esta funcionalidad es a menudo solamente &#x00fa;til para modelos de datos
+                heredados; recomendamos menos tablas que clases un modelo de dominio m&#x00e1;s
+                granularizado. Sin embargo, es &#x00fa;til para cambiar entre estrategias de mapeo
+                de herencias en una misma jerarqu&#x00ed;a, como se explica luego.
+            </para>
+
+        </sect2>
+
+        <sect2 id="mapping-declaration-key">
+            <title>key</title>
+
+            <para>
+                Hasta ahora hemos visto el elemento <literal>&lt;key&gt;</literal> pocas veces.
+                Aparece en cualquier sitio en que el elemento padre de mapeo defina una uni&#x00f3;n
+                a una nueva tabla, y define la clave for&#x00e1;nea en la tabla unida,
+                que referencia la clave primaria de la tabla original.
+            </para>
+
+            <programlistingco>
+                <areaspec>
+                    <area id="key1" coords="2 50"/>
+                    <area id="key2" coords="3 50"/>
+                    <area id="key3" coords="4 50"/>
+                    <area id="key4" coords="5 50"/>
+                    <area id="key5" coords="6 50"/>
+                    <area id="key6" coords="7 50"/>
+                </areaspec>
+                <programlisting><![CDATA[<key
+        column="columnname"
+        on-delete="noaction|cascade"
+        property-ref="propertyName"
+        not-null="true|false"
+        update="true|false"
+        unique="true|false"
+/>]]></programlisting>
+
+                <calloutlist>
+                    <callout arearefs="key1">
+                        <para>
+                            <literal>column</literal> (opcional): El nombre de columna de la clave for&#x00e1;nea.
+                            Puede ser tambi&#x00e9;n especificado por elemento(s) anidado(s)
+                            <literal>&lt;column&gt;</literal>.
+                        </para>
+                    </callout>
+                    <callout arearefs="key2">
+                        <para>
+                            <literal>on-delete</literal> (opcional, por defecto a <literal>noaction</literal>): 
+                            Especifica si la restricci&#x00f3;n de clave for&#x00e1;nea tiene el borrado en cascada
+                            habilitado a nivel de base de datos.
+                        </para>
+                    </callout>
+                    <callout arearefs="key3">
+                        <para>
+                            <literal>property-ref</literal> (opcional): Especifica que la clave for&#x00e1;nea
+                            referencia columnas que no son del la clave primaria de la tabla original.
+                            (Provisto para datos heredados.)
+                        </para>
+                    </callout>
+                    <callout arearefs="key4">
+                        <para>
+                            <literal>not-null</literal> (opcional): Especifica que las columnas de la clave
+                            for&#x00e1;nea son no nulables (esto est&#x00e1; implicado si la clave for&#x00e1;nea
+                            es tambi&#x00e9;n parte de la clave primaria).
+                        </para>
+                    </callout>
+                    <callout arearefs="key5">
+                        <para>
+                            <literal>update</literal> (opcional): Especifica que la clave for&#x00e1;nea nunca
+                            debe ser actualizada (esto est&#x00e1; implicado si la clave for&#x00e1;nea
+                            es tambi&#x00e9;n parte de la clave primaria).
+                        </para>
+                    </callout>
+                    <callout arearefs="key6">
+                        <para>
+                            <literal>unique</literal> (opcional): Especifica que la clave for&#x00e1;nea
+                            debe tener una restricci&#x00f3;n de unicidad (esto est&#x00e1; implicado si
+                            la clave for&#x00e1;nea es tambi&#x00e9;n la clave primaria).
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+
+            <para>
+                Recomendamos que, para los sistemas en donde el rendimiento sea importante, todas las
+                claves deben ser definidas <literal>on-delete="cascade"</literal>, e Hibernate usar&#x00e1;
+                una restricci&#x00f3;n <literal>ON CASCADE DELETE</literal> a nivel de base de datos,
+                en vez de muchas sentencias <literal>DELETE</literal> individuales. Ten en cuenta que
+                esta funcionalidad se salta la habitual estrategia de bloqueo optimista de Hibernate para
+                datos versionados.
+            </para>
+            
+            <para>
+                Los atributos <literal>not-null</literal> y <literal>update</literal> son &#x00fa;tiles
+                al mapear una asociaci&#x00f3;n uno a muchos unidireccional. Si mapeas una uno a muchos
+                unidireccional a una clave for&#x00e1;nea no nulable, <emphasis>debes</emphasis> declarar
+                la columna clave usando <literal>&lt;key not-null="true"&gt;</literal>.
+            </para>
+
+        </sect2>
+
+        <sect2 id="mapping-column" revision="3">
+           <title>los elementos column y formula</title>
+           <para>
+               Cualquier elemento de mapeo que acepte un atributo <literal>column</literal> aceptar&#x00e1;
+               alternativamente un subelemento <literal>&lt;column&gt;</literal>. De forma similar,
+               <literal>&lt;formula&gt;</literal> es una alternativa al atributo <literal>formula</literal>.
+           </para>
+
+           <programlisting><![CDATA[<column
+        name="column_name"
+        length="N"
+        precision="N"
+        scale="N"
+        not-null="true|false"
+        unique="true|false"
+        unique-key="multicolumn_unique_key_name"
+        index="index_name"
+        sql-type="sql_type_name"
+        check="SQL expression"/>]]></programlisting>
+
+            <programlisting><![CDATA[<formula>expresi&#x00f3;n SQL</formula>]]></programlisting>
+        
+            <para>
+                Los atributos <literal>column</literal> y <literal>formula</literal> pueden
+                incluso ser combinados dentro del mismo mapeo de propiedad o asociaci&#x00f3;n para
+                expresar, por ejemplo, condiciones de uni&#x00f3;n ex&#x00f3;ticas.
+            </para>
+
+            <programlisting><![CDATA[<many-to-one name="homeAddress" class="Address"
+        insert="false" update="false">
+    <column name="person_id" not-null="true" length="10"/>
+    <formula>'MAILING'</formula>
+</many-to-one>]]></programlisting>
+
+    </sect2>  
+   	
+        <sect2 id="mapping-declaration-import">
+            <title>import</title>
+
+            <para>
+                Sup&#x00f3;n que tu aplicaci&#x00f3;n tiene dos clases persistentes con el mismo nombre,
+                y no quieres especificar el nombre completamenta cualificado (paquete) en las consultas
+                Hibernate. Las clases pueden ser "importadas" expl&#x00ed;citamente, en vez de confiar en
+                <literal>auto-import="true"</literal>. Puedes incluso importar clases e interfaces que
+                no est&#x00e9;n mapeadas expl&#x00ed;citamente.
+            </para>
+            
+            <programlisting><![CDATA[<import class="java.lang.Object" rename="Universe"/>]]></programlisting>
+            
+            <programlistingco>
+                <areaspec>
+                    <area id="import1" coords="2 40"/>
+                    <area id="import2" coords="3 40"/>
+                </areaspec>
+                <programlisting><![CDATA[<import
+        class="ClassName"
+        rename="ShortName"
+/>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="import1">
+                        <para>
+                            <literal>class</literal>: El nombre de clase completamente cualificado de
+                            cualquier clase Java.
+                        </para>              
+                    </callout>                   
+                    <callout arearefs="import2">
+                        <para>
+                            <literal>rename</literal> (opcional - por defecto al nombre de clase sin cualificar):
+                            Un nombre que ser&#x00e1; usado en el leguaje de consulta.
+                        </para>               
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+            
+        </sect2>
+
+        <sect2 id="mapping-types-anymapping" revision="2">
+            <title>any</title>
+            
+            <para>
+                Hay un tipo m&#x00e1;s de mapeo de propiedad. El elemento de mapeo <literal>&lt;any&gt;</literal>
+                define una asociaci&#x00e1;n polim&#x00f3;rfica a clases desde m&#x00fa;ltiples tablas. Este tipo
+                de mapeo siempre requiere m&#x00e1;s de una columna. La primera columna contiene el tipo de la
+                entidad asociada. Las columnas restantes contienen el identificador. Es imposible especificar una
+                restricci&#x00f3;n de clave for&#x00e1;nea para este tipo de asociaci&#x00f3;n, por lo que
+                esto ciertamente no est&#x00e1; concebido como la forma habitual de mapear asociaciones
+                (polim&#x00f3;rficas). S&#x00f3;lo debes usar esto en casos muy especiales (por ejemplo,
+                trazas de auditor&#x00e9;a, datos de sesi&#x00f3;n de usuario, etc).
+            </para>
+
+            <para>
+                 El atributo <literal>meta-type</literal> permite a la aplicaci&#x00f3;n especificar un tipo
+                 personalizado que mapee columnas de base de datos a clases persistentes que tengan propiedades
+                 identificadoras del tipo especificado por <literal>id-type</literal>. Debes especificar el
+                 mapeo de valores del meta-type a nombres de clase.
+            </para>
+
+            <programlisting><![CDATA[<any name="being" id-type="long" meta-type="string">
+    <meta-value value="TBL_ANIMAL" class="Animal"/>
+    <meta-value value="TBL_HUMAN" class="Human"/>
+    <meta-value value="TBL_ALIEN" class="Alien"/>
+    <column name="table_name"/>
+    <column name="id"/>
+</any>]]></programlisting>
+
+            <programlistingco>
+                <areaspec>
+                    <area id="any1" coords="2 50"/>
+                    <area id="any2" coords="3 50"/>
+                    <area id="any3" coords="4 50"/>
+                    <area id="any4" coords="5 50"/>
+                    <area id="any5" coords="6 50"/>
+                    <area id="any6" coords="7 50"/>
+                </areaspec>
+                <programlisting><![CDATA[<any
+        name="propertyName"
+        id-type="idtypename"
+        meta-type="metatypename"
+        cascade="cascade_style"
+        access="field|property|ClassName"
+        optimistic-lock="true|false"
+>
+        <meta-value ... />
+        <meta-value ... />
+        .....
+        <column .... />
+        <column .... />
+        .....
+</any>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="any1">
+                        <para>
+                            <literal>name</literal>: el nombre de la propiedad.
+                        </para>            
+                    </callout>                   
+                    <callout arearefs="any2">
+                        <para>
+                            <literal>id-type</literal>: el tipo del identificador.
+                        </para>            
+                    </callout>                   
+                    <callout arearefs="any3">
+                        <para>
+                            <literal>meta-type</literal> (opcional - por defecto a <literal>string</literal>): 
+                            Cualquier tipo que sea permitido para un mapeo de discriminador.
+                        </para>            
+                    </callout>                   
+                    <callout arearefs="any4">
+                        <para>
+                            <literal>cascade</literal> (opcional- por defecto a <literal>none</literal>): 
+                            el estilo de cascada.
+                        </para>            
+                    </callout>                   
+                    <callout arearefs="any5">
+                        <para>
+                            <literal>access</literal> (opcional - por defecto a <literal>property</literal>): La
+                            estrategia que Hibernate debe usar para acceder al valor de la propiedad.
+                        </para>
+                    </callout>
+                    <callout arearefs="any6">
+                        <para>
+                            <literal>optimistic-lock</literal> (opcional - por defecto a <literal>true</literal>):
+                            Especifica si las actualizaciones de esta propiedad requieren o no de la
+                            adquisici&#x00f3;n del bloqueo optimista. En otras palabras, determina si debe ocurrir
+                            un incremento de versi&#x00f3;n cuando esta propiedad est&#x00e1; desactualizada.
+                        </para>
+                    </callout>
+                </calloutlist>
+            </programlistingco>
+
+      </sect2>
+
+    </sect1>
+
+    <sect1 id="mapping-types">
+        <title>Tipos de Hibernate</title>
+
+        <sect2 id="mapping-types-entitiesvalues" revision="1">
+            <title>Entidades y Valores</title>
+
+            <para>
+                Para entender el comportamiento de varios objetos a nivel de lenguaje Java
+                con respecto al servicio de persistencia, necesitamos clasificarlos en dos grupos:
+            </para>
+
+            <para>
+                Una <emphasis>entidad</emphasis> existe independientemente de cualquier otros
+                objetos que referencien a la entidad. Contrasta esto con el model habitual de Java
+                donde un objeto desreferenciado es recolectado como basura. Las entidades deben ser
+                salvadas y borradas expl&#x00ed;citamente (excepto que las grabaciones y borrados
+                puedan ser <emphasis>tratados en cascada</emphasis> desde una entidad padre a sus hijos).
+                Esto es diferente al modelo de persistencia de objetos por alcance - y se corresponde
+                m&#x00e1;s de cerca a c&#x00f3;mo los objetos de aplicaci&#x00f3;n son usados
+                habitualmente en grandes sistemas. Las entidades soportan referencias circulares y
+                compartidas, que tambi&#x00e9; pueden ser versionadas.
+            </para>
+
+            <para>
+                El estado persistente de una entidad consiste en referencias a otras entidades
+                e instancias de tipo <emphasis>valor</emphasis>. Los valores son primitivos,
+                colecciones (no lo que est&#x00e1; dentro de la colecci&#x00f3;n), componentes
+                y ciertos objetos inmutables. A diferencia de las entidades, los valores
+                (en particular las colecciones y los componentes) <emphasis>son</emphasis>
+                hechos persitentes y borrados por alcance. Como los objetos valor (y primitivos)
+                son persistidos y borrados junto a sus entidades contenedoras, no pueden ser
+                versionados independientemente. Los valores no tienen identidad independiente,
+                por los que no pueden ser compartidos por dos entidades o colleciones.
+            </para>
+
+            <para>
+                Hasta ahora, hemos estado usando el t&#x00e9;rmino "clase persistente"
+                para referirnos a entidades. Continuaremos haci&#x00e9;ndolo. Hablando
+                estrictamente, sin embargo, no todas la clases  con estado persistente
+                definidas por el usuario son entidades. Un <emphasis>componente</emphasis>
+                es una clase definida por el usuario con sem&#x00e1;ntica de valor.
+                Una propiedad Java de tipo <literal>java.lang.String</literal> tambi&#x00e9;n
+                tiene sem&#x00e1;ntica de valor. Dada esta definici&#x00f3;n, podemos decir
+                que todos los tipo (clases) provistos por el JDK tienen una sem&#x00e1;ntica
+                de tipo valor en Java, mientras que los tipos definidos por el usuario
+                pueden ser mapeados con sem&#x00e1;ntica de tipo valor o de entidad.
+                La desici&#x00f3;n corre por cuenta del desarrollador de la aplicaci&#x00f3;n.
+                Un buen consejo para una clase entidad en un modelo de dominio son las referencias
+                compartidas a una sola instancia de esa clase, mientras que la composici&#x00f3;n
+                o agregaci&#x00f3;n usualmente se traducen a un tipo de valor.
+            </para>
+
+            <para>
+                Volveremos a visitar ambos conceptos a lo largo de la documentaci&#x00f3;n.
+            </para>
+
+            <para>
+                EL desaf&#x00ed;o es mapear el sistema de tipos de Java (y la definici&#x00f3;n
+                de entidades y tipos de valor de los desarrolladores) al sistema de tipos de
+                SQL/base de datos. EL puente entre ambos sistemas es provisto por Hibernate:
+                para las entidades usamos <literal>&lt;class&gt;</literal>,
+                <literal>&lt;subclass&gt;</literal>, etc. Para los tipos de valor usamos
+                <literal>&lt;property&gt;</literal>, <literal>&lt;component&gt;</literal>, etc,
+                usualmente con un atributo <literal>type</literal>. El valor de este atributo
+                es el nombre de un <emphasis>tipo de mapeo</emphasis> de Hibernate. Hibernate
+                provee de f&#x00e1;brica muchos mapeos (para tipos de valores del JDK
+                est&#x00e1;ndar). Puedes escribir tus propios mapeos de tipo, as&#x00ed; como 
+                implementar tus estrategias de conversi&#x00f3;n personalizadas, como veremos luego.
+            </para>
+
+            <para>
+                Todos los tipos prefabricados de Hibernate soportan sem&#x00e1;ntica de nulos
+                excepto las colecciones.
+            </para>
+
+        </sect2>
+
+        <sect2 id="mapping-types-basictypes" revision="2">
+            <title>Tipos de valores b&#x00e1;sicos</title>
+
+            <para>
+                Los <emphasis>tipos de mapeo b&#x00e1;sicos</emphasis> prefabricados pueden ser
+                categorizado a grandes rasgos en:
+
+                <variablelist>
+                    <varlistentry>
+                        <term><literal>integer, long, short, float, double, character, byte,
+                            boolean, yes_no, true_false</literal></term>
+                        <listitem>
+                            <para>
+                                Mapeos de tipos primitivos de Java o clases de envoltura a
+                                la tipos de columna SQL (espec&#x00ed;cifica del vendedor).
+                                <literal>boolean, yes_no</literal> y <literal>true_false</literal>
+                                son codificaciones alternativas a <literal>boolean</literal> de
+                                Java o <literal>java.lang.Boolean</literal>.
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>string</literal></term>
+                        <listitem>
+                            <para>
+                                Un mapeo del tipo <literal>java.lang.String</literal> a
+                                <literal>VARCHAR</literal> (u Oracle <literal>VAARCHAR2</literal>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>date, time, timestamp</literal></term>
+                        <listitem>
+                            <para>
+                                Mapeos de tipo desde <literal>java.util.Date</literal> y sus subclases
+                                a tipos SQL <literal>DATE</literal>, <literal>TIME</literal> y
+                                <literal>TIMESTAMP</literal> (o equivalente).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>calendar, calendar_date</literal></term>
+                        <listitem>
+                            <para>
+                                Mapeos de tipo desde <literal>java.util.Date</literal> y sus subclases
+                                a tipos SQL <literal>TIMESTAMP</literal> y <literal>DATE</literal>
+                                (o equivalente).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>big_decimal, big_integer</literal></term>
+                        <listitem>
+                            <para>
+                                Mapeos de tipo desde <literal>java.math.BigDecimal</literal> y
+                                <literal>java.math.BigInteger</literal> a <literal>NUMERIC</literal> 
+                                (o <literal>NUMBER</literal> de Oracle).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>locale, timezone, currency</literal></term>
+                        <listitem>
+                            <para>
+                                Mapeos de tipo desde <literal>java.util.Locale</literal>,
+                                <literal>java.util.TimeZone</literal> y 
+                                <literal>java.util.Currency</literal> a 
+                                <literal>VARCHAR</literal> (o <literal>VARCHAR2</literal> de Oracle).
+                                Las instancias de <literal>Locale</literal> y <literal>Currency</literal>
+                                son mapeadas a sus c&#x00f3;digos ISO. Las instancias de
+                                <literal>TimeZone</literal> son mapeadas a sus <literal>ID</literal>.
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>class</literal></term>
+                        <listitem>
+                            <para>
+                                Un mapeo de tipo <literal>java.lang.Class</literal> a
+                                <literal>VARCHAR</literal> (o <literal>VARCHAR2</literal> de Oracle).
+                                Una <literal>Class</literal> es mapeara a su nombre completamente
+                                cualificado.
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>binary</literal></term>
+                        <listitem>
+                            <para>
+                                Mapea arreglos de bytes a un tipo binario SQL apropiado.
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>text</literal></term>
+                        <listitem>
+                            <para>
+                                Mapea cadenas largas Java al tipo SQL <literal>CLOB</literal> o
+                                <literal>TEXT</literal>.
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>serializable</literal></term>
+                        <listitem>
+                            <para>
+                                Mapea tipos serializables Java a un tipo binario SQL apropiado.
+                                Puedes adem&#x00e1;s indicar el tipo <literal>serializable</literal>
+                                de Hibernate con el nombre de una clase o interface serializable Java
+                                que no sea por defecto un tipo b&#x00e1;sico.
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><literal>clob, blob</literal></term>
+                        <listitem>
+                            <para>
+                                Mapeos de tipo para las clases JDBC <literal>java.sql.Clob</literal> y
+                                <literal>java.sql.Blob</literal>. Estos tipos pueden ser inconvenientes
+                                para algunas aplicaciones, pues el objeto blob o clob no puede ser reusado
+                                fuera de una transacci&#x00f3;n (Adem&#x00e1;s, el soporte del driver suele
+                                ser malo e inconsistente).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            
+            </para>
+
+            <para>
+                Los identificadores &#x00fa;nicos de entidades y collecciones pueden ser de cualquier
+                tipo b&#x00e1;sico excepto <literal>binary</literal>, <literal>blob</literal>
+                y <literal>clob</literal>. 
+                (Los identificadores compuestos est&#x00e1;n tambi&#x00e9;n permitidos, ver debajo.)
+            </para>
+            
+            <para>
+                Los tipos de valor b&#x00e1;sicos tienen sus constantes <literal>Type</literal>
+                correspondientes definidas en <literal>org.hibernate.Hibernate</literal>. Por ejemplo,
+                <literal>Hibernate.STRING</literal> representa el tipo <literal>string</literal>.
+            </para>
+
+        </sect2>
+
+        <sect2 id="mapping-types-custom" revision="2">
+            <title>Tipos de valor personalizados</title>
+
+            <para>
+                Es relativamente f&#x00e1;cil para los desarrolladores crear sus propios tipos de valor.
+                Por ejemplo, podr&#x00ed;as querer persistir propiedades del tipo <literal>java.lang.BigInteger</literal>
+                a columnas <literal>VARCHAR</literal>. Hibernate no provee un tipo de f&#x00e1;brica para esto.
+                Pero los tipos personalizados no est&#x00e1;n limitados a mapear una propiedad (o elemento de colecci&#x00f3;n)
+                a una sola columna de tabla. As&#x00ed;, por ejemplo, podr&#x00ed;as tener una propiedad Java
+                <literal>getName()</literal>/<literal>setName()</literal> de tipo <literal>java.lang.String</literal>
+                que fuera persistida a las columnas <literal>FIRST_NAME</literal>, <literal>INITIAL</literal>,
+                <literal>SURNAME</literal>.
+            </para>
+            
+            <para>
+                Para implementar un tipo personalizado, implementa bien <literal>org.hibernate.UserType</literal>
+                o <literal>org.hibernate.CompositeUserType</literal> y declara las propiedades usando el nombre
+                de clase completamente cualificado del tipo. Revisa <literal>org.hibernate.test.DoubleStringType</literal>
+                para ver qu&#x00e9; tipo de cosas son posibles.
+            </para>
+
+            <programlisting><![CDATA[<property name="twoStrings" type="org.hibernate.test.DoubleStringType">
+    <column name="first_string"/>
+    <column name="second_string"/>
+</property>]]></programlisting>
+
+            <para>
+                Observa el uso de etiquetas <literal>&lt;column&gt;</literal> para mapear una propiedad
+                a m&#x00fa;ltiples columnas.
+            </para>
+            
+            <para>
+                Las interfaces <literal>CompositeUserType</literal>, <literal>EnhancedUserType</literal>,
+                <literal>UserCollectionType</literal>, y <literal>UserVersionType</literal> proveen
+                soporte a usos m&#x00e1;s especializados.
+            </para>
+            
+            <para>
+                Puedes incluso proveer de par&#x00e1;metros a un <literal>UserType</literal> en el 
+                fichero de mapeo. Para hacer esto, tu <literal>UserType</literal> debe implementar
+                la interface <literal>org.hibernate.usertype.ParameterizedType</literal>. Para
+                proveer de par&#x00e1;metros a tu tipo personalizado, puedes usar el elemento 
+                <literal>&lt;type&gt;</literal> en tus ficheros de mapeo.
+            </para>
+            
+            <programlisting><![CDATA[<property name="priority">
+    <type name="com.mycompany.usertypes.DefaultValueIntegerType">
+        <param name="default">0</param>
+    </type>
+</property>]]></programlisting>
+
+            <para>
+                Ahora el <literal>UserType</literal> puede recuperar el valor del par&#x00e1;metro
+                llamado <literal>default</literal> del objeto <literal>Properties</literal>
+                que se le pasa.
+            </para>
+            
+            <para>
+                Si usas cierto <literal>UserType</literal> muy frecuentemente, puede ser &#x00fa;til
+                definir un nombre corto para &#x00e9;. Puedes hacer esto usando el elemento
+                <literal>&lt;typedef&gt;</literal>. Los typedefs asignan un nombre a un tipo
+                personalizado, y pueden tambi&#x00e9;n contener una lista de valores por defecto
+                de par&#x00e1;metros si el tipo fuese parametrizado.
+            </para>
+            
+            <programlisting><![CDATA[<typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero">
+    <param name="default">0</param>
+</typedef>]]></programlisting>
+
+            <programlisting><![CDATA[<property name="priority" type="default_zero"/>]]></programlisting>
+
+            <para>
+                tambi&#x00e9;n es posible sobrescribir los par&#x00e1;metros provistos en un typedef sobre
+                una base caso por caso usando par&#x00e1;metros de tipo en el mapeo de la propiedad.
+            </para>
+            
+            <para>
+                Aunque el rico espectro de tipos prefabricados y soporte de componentes de Hibernate
+                significa que raramente <emphasis>necesites</emphasis> usar un tipo personalizado;
+                sin embargo se considera una buena forma usar tipos personalizados para clases (no-entidades)
+                que aparezcan frecuentemente en tu aplicaci&#x00f3;n. Por ejemplo, una clase
+                <literal>MonetaryAmount</literal> es una buena candidata para un
+                <literal>CompositeUserType</literal>, incluso cuando puede ser facilmente mapeada como un
+                componente. Un motivo para esto es la abstracci&#x00f3;n. Con un tipo personalizado,
+                tus documentos de mapeo estar&#x00e1; impermeabilizados contra posibles cambios futuros en la
+                forma de representar valores monetarios.
+            </para>
+        </sect2>
+
+    </sect1>
+
+
+    <sect1 id="mapping-entityname">
+        <title>Mapeando una clase m&#x00e1;s de una vez</title>
+        <para>
+            Es posible proveer m&#x00e1;s de un mapeo para una clase persistente en particular. En este caso debes
+            especificar un <emphasis>nombre de entidad</emphasis> para desambiguar entr las instancias de las
+            dos entidades mapeadas. (Por defectom, el nombre de la entidad es el mismo que el nombre de la clase.)
+            Hibernate te deja especificar el nombre de entidad al trabajar con objetos persistentes, al escribir
+            consultas, o al mapear asociaciones a la entidad mencionada.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Contract" table="Contracts" 
+        entity-name="CurrentContract">
+    ...
+    <set name="history" inverse="true" 
+            order-by="effectiveEndDate desc">
+        <key column="currentContractId"/>
+        <one-to-many entity-name="HistoricalContract"/>
+    </set>
+</class>
+
+<class name="Contract" table="ContractHistory" 
+        entity-name="HistoricalContract">
+    ...
+    <many-to-one name="currentContract" 
+            column="currentContractId" 
+            entity-name="CurrentContract"/>
+</class>]]></programlisting>
+
+        <para>
+            Observa c&#x00f3;mo las asociaciones ahora se especifican usando <literal>entity-name</literal> en vez de
+            <literal>class</literal>.
+        </para>
+
+    </sect1>
+
+
+    <sect1 id="mapping-quotedidentifiers">
+            <title>identificadores SQL encomillados</title>
+            <para>
+                Puedes forzar a Hibernate a encomillar un identificador en el SQL generado encerrando el nombre
+                de tabla o columna entre backticks en el documento de mapeo. Hibernate usar&#x00e1; el estilo de
+                encomillado para el <literal>Dialect</literal> SQL (usualmente comillas dobles, excepto corchetes
+                para SQL Server y backsticks para MySQL).
+            </para>
+
+            <programlisting><![CDATA[<class name="LineItem" table="`Line Item`">
+    <id name="id" column="`Item Id`"/><generator class="assigned"/></id>
+    <property name="itemNumber" column="`Item #`"/>
+    ...
+</class>]]></programlisting>
+
+    </sect1>
+
+  	
+   	<sect1 id="mapping-alternatives">
+   	<title>Alternativas de metadatos</title>
+   	
+   	<para>
+            XML no es para todos, as&#x00e1; que hay algunas formas alternativas de definir metadatos de mapeo O/R
+            en Hibernate.
+   	</para>
+
+    <sect2 id="mapping-xdoclet">
+        <title>Usando marcado de XDoclet</title>
+
+        <para>
+            Muchos usuarios de Hibernate prefieren embeber la informaci&#x00f3;n de mapeo directamente
+            en el c&#x00f3;digo fuente usando las <literal>@hibernate.etiquetas</literal> XDoclet.
+            No cubriremos este enfoque en este documento, pues estrictamente es considerado parte
+            de XDoclet. Sin embargo, inclu&#x00ed;mos el siguiente ejemplo de la clase
+            <literal>Cat</literal> con mapeos XDoclet.
+        </para>
+
+        <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+/**
+ * @hibernate.class
+ *  table="CATS"
+ */
+public class Cat {
+    private Long id; // identifier
+    private Date birthdate;
+    private Cat mother;
+    private Set kittens
+    private Color color;
+    private char sex;
+    private float weight;
+
+    /*
+     * @hibernate.id
+     *  generator-class="native"
+     *  column="CAT_ID"
+     */
+    public Long getId() {
+        return id;
+    }
+    private void setId(Long id) {
+        this.id=id;
+    }
+
+    /**
+     * @hibernate.many-to-one
+     *  column="PARENT_ID"
+     */
+    public Cat getMother() {
+        return mother;
+    }
+    void setMother(Cat mother) {
+        this.mother = mother;
+    }
+
+    /**
+     * @hibernate.property
+     *  column="BIRTH_DATE"
+     */
+    public Date getBirthdate() {
+        return birthdate;
+    }
+    void setBirthdate(Date date) {
+        birthdate = date;
+    }
+    /**
+     * @hibernate.property
+     *  column="WEIGHT"
+     */
+    public float getWeight() {
+        return weight;
+    }
+    void setWeight(float weight) {
+        this.weight = weight;
+    }
+
+    /**
+     * @hibernate.property
+     *  column="COLOR"
+     *  not-null="true"
+     */
+    public Color getColor() {
+        return color;
+    }
+    void setColor(Color color) {
+        this.color = color;
+    }
+    /**
+     * @hibernate.set
+     *  inverse="true"
+     *  order-by="BIRTH_DATE"
+     * @hibernate.collection-key
+     *  column="PARENT_ID"
+     * @hibernate.collection-one-to-many
+     */
+    public Set getKittens() {
+        return kittens;
+    }
+    void setKittens(Set kittens) {
+        this.kittens = kittens;
+    }
+    // addKitten not needed by Hibernate
+    public void addKitten(Cat kitten) {
+        kittens.add(kitten);
+    }
+
+    /**
+     * @hibernate.property
+     *  column="SEX"
+     *  not-null="true"
+     *  update="false"
+     */
+    public char getSex() {
+        return sex;
+    }
+    void setSex(char sex) {
+        this.sex=sex;
+    }
+}]]></programlisting>
+
+        <para>
+            Para m&#x00e1;s ejemplos de XDoclet e Hibernate ver en el sitio web de Hibernate.
+        </para>
+
+    </sect2>
+
+    <sect2 id="mapping-annotations" revision="2">
+        <title>Usando anotaciones JDK 5.0</title>
+        <para>
+            El JDK 5.0 introdujo anotaciones del estilo XDoclet a nivel del lenguaje,
+            con chequeo seguro de tipos en tiempo de compilaci&#x00f3;n. Este mecanismo es m&#x00e1;s
+            potente y que las anotaciones XDoclet, y mejor soportado por herramientas e IDEs.
+            IntelliJ IDEA, por ejemplo, soporta auto-compleci&#x00f3;n y resaltado de sintaxis de anotaciones
+            JDK 5.0. La nueva revisi&#x00f3;n de la especificaci&#x00f3;n de EJB (JSR-220) usa anotaciones
+            JDK 5.0 como el mecanismo primario de metadatos para beans de entidad. Hibernate3 implementa
+            el <literal>EntityManager</literal> del JSR-220 (la API de persistencia), y el soporte para
+            metadatos de mapeo est&#x00e1; disponible v&#x00ed;a el paquete <emphasis>Hibernate Annotations</emphasis>,
+            como una descarga por separado. Tanto metadatos de EJB3 (JSR-220) como de Hibernate3 est&#x00e1;n soportados.
+        </para>
+
+        <para>
+            Este es un ejemplo de una clase POJO anotada como un bean de entidad EJB:
+        </para>
+
+        <programlisting><![CDATA[@Entity(access = AccessType.FIELD)
+public class Customer implements Serializable {
+
+    @Id;
+    Long id;
+
+    String firstName;
+    String lastName;
+    Date birthday;
+
+    @Transient
+    Integer age;
+
+    @Embedded
+    private Address homeAddress;
+
+    @OneToMany(cascade=CascadeType.ALL)
+
+    @JoinColumn(name="CUSTOMER_ID")
+    Set<Order> orders;
+
+    // Getter/setter and business methods
+}]]></programlisting>
+
+        <para>
+            Ten en cuenta que el soporte a anotaciones JDK 5.0 (y JSR-220) es todav&#x00ed;a un
+            trabajo en progreso y no completado. Por favor, para m&#x00e1;s detalles refi&#x00e9;rete al modulo
+            de Anotaciones de Hibernate.
+        </para>
+    
+    </sect2>
+    </sect1>
+
+</chapter>
+
+
+
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/batch.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/batch.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/batch.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/batch.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,192 @@
+<chapter id="batch">
+    <title>Procesamiento por lotes</title>
+    
+    <para>
+        Un enfoque ingenuo para insertar 100.000 filas en la base de datos usando Hibernate podría verse así:
+    </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+for ( int i=0; i<100000; i++ ) {
+    Customer customer = new Customer(.....);
+    session.save(customer);
+}
+tx.commit();
+session.close();]]></programlisting>
+
+    <para>
+        Esto podría caer sobre una <literal>OutOfMemoryException</literal> en algún sitio
+        cerca de la fila 50.000. Esto es porque Hibernate tiene en caché todas las instancias
+        de <literal>Customer</literal> recién instanciadas en el caché de nivel de sesión.
+    </para>
+
+    <para>
+        En este capítulo te mostraremos cómo evitar este problema. Primero, sin embargo,
+        si estás haciendo procesamiento por lotes (batch processing), es absolutamente crítico
+        que habilites el uso de loteo JDBC, si pretendes lograr un rendimiento razonable.
+        Establece el tamaño de lote JDBC a un número razonable (digamos 10-50):
+    </para>
+    
+<programlisting><![CDATA[hibernate.jdbc.batch_size 20]]></programlisting>
+
+    <para>
+        Podrías además querer hacer este tipo de trabajo en un proceso donde la interacción con el caché de
+        segundo nivel esté completamente deshabilitado:
+    </para>
+
+<programlisting><![CDATA[hibernate.cache.use_second_level_cache false]]></programlisting>
+
+    <sect1 id="batch-inserts">
+        <title>Inserciones en lote</title>
+
+        <para>
+            Al hacer persistentes objetos nuevos, debes limpiar con <literal>flush()</literal> y
+            llamar a <literal>clear()</literal> en la sesión regularmente, para controlar el tamaño
+            del caché de primer nivel.
+        </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+   
+for ( int i=0; i<100000; i++ ) {
+    Customer customer = new Customer(.....);
+    session.save(customer);
+    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
+        //flush a batch of inserts and release memory:
+        session.flush();
+        session.clear();
+    }
+}
+   
+tx.commit();
+session.close();]]></programlisting>
+
+    </sect1>
+
+    <sect1 id="batch-update" >
+        <title>Actualizaciones en lote</title>
+
+        <para>
+            Para recuperar y actualizar datos se aplican las mismas ideas. Adicionalmente, necesitas usar
+            <literal>scroll()</literal> para sacar ventaja de los cursores del lado del servidor en consultas
+            que devuelvan muchas filas de datos.
+        </para>
+
+<programlisting><![CDATA[Session session = sessionFactory.openSession();
+Transaction tx = session.beginTransaction();
+   
+ScrollableResults customers = session.getNamedQuery("GetCustomers")
+    .setCacheMode(CacheMode.IGNORE)
+    .scroll(ScrollMode.FORWARD_ONLY);
+int count=0;
+while ( customers.next() ) {
+    Customer customer = (Customer) customers.get(0);
+    customer.updateStuff(...);
+    if ( ++count % 20 == 0 ) {
+        //flush a batch of updates and release memory:
+        session.flush();
+        session.clear();
+    }
+}
+   
+tx.commit();
+session.close();]]></programlisting>
+
+    </sect1>
+
+    <sect1 id="batch-direct">
+        <title>update/delete en masa</title>
+
+        <para>
+            Como ya se ha discutido, el mapeo objeto/relacional automático y transparente se refiere
+            al manejo de estado de objetos. Esto implica que el estado del objeto está disponible
+            en memoria, por lo tanto actualizar o borrar (usando <literal>UPDATE</literal> y
+            <literal>DELETE</literal> de SQL) datos directamente en la base de datos no afectará el
+            estado en memoria. Sin embargo, Hibernate provee métodos para la ejecución de sentencias
+            del estilo de <literal>UPDATE</literal> y <literal>DELETE</literal> de SQL que se realizan
+            a través del Lenguaje de Consulta de Hibernate (Hibernate Query Language o
+            <xref linkend="queryhql">HQL</xref>).
+        </para>
+
+	    <para>
+            La pseudo-sintáxis para sentencias <literal>UPDATE</literal> y <literal>DELETE</literal> es:
+            <literal>( UPDATE | DELETE ) FROM? ClassName (WHERE WHERE_CONDITIONS)?</literal>. Algunos puntos
+            a tener en cuenta:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    En la cláusula-from, la palabra clave FROM es opcional
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Puede haber sólo una clase mencionada en la cláusula-from, y <emphasis>no puede</emphasis>
+                    tener un alias.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    No puede especificarse ningún join (bien implícito o explícito) en una consulta masiva de HQL.
+                    Pueden usarse subconsultas en la cláusula-where.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    La cláusula-where es también opcional.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Como un ejemplo, para ejecutar un <literal>UPDATE</literal> HQL, usa el
+            método <literal>Query.executeUpdate()</literal>:
+        </para>
+
+        <programlisting><![CDATA[Session session = sessionFactory.openSession();
+        Transaction tx = session.beginTransaction();
+
+        String hqlUpdate = "update Customer set name = :newName where name = :oldName";
+        int updatedEntities = s.createQuery( hqlUpdate )
+                            .setString( "newName", newName )
+                            .setString( "oldName", oldName )
+                            .executeUpdate();
+        tx.commit();
+        session.close();]]></programlisting>
+
+        <para>
+            Para ejecutar un <literal>DELETE</literal> HQL, usa el mismo método <literal>Query.executeUpdate()</literal>
+            (el método está nombrado para aquellos familiarizados con
+            <literal>PreparedStatement.executeUpdate()</literal> de JDBC):
+        </para>
+
+        <programlisting><![CDATA[Session session = sessionFactory.openSession();
+        Transaction tx = session.beginTransaction();
+
+        String hqlDelete = "delete Customer where name = :oldName";
+        int deletedEntities = s.createQuery( hqlDelete )
+                            .setString( "oldName", oldName )
+                            .executeUpdate();
+        tx.commit();
+        session.close();]]></programlisting>
+
+        <para>
+            El valor <literal>int</literal> devuelto por el método <literal>Query.executeUpdate()</literal>
+            indica el número de entidades afectadas por la operación. Considera que esto puede o no
+            correlacionarse al número de filas afectadas en la base de datos. Una operación masiva HQL podría
+            resultar en que se ejecuten múltiples sentencias de SQL reales, para joined-subclass, por ejemplo.
+            El número devuelto indica el número de entidades reales afectadas por la sentencia. Volviendo al
+            ejemplo de joined-subclass, un borrado contra una de las subclases puede resultar realmente en
+            borrados contra no sólo la tabla a la que está mapeada esa subclase, sino también la tabla "raíz"
+            y potencialmente tablas de joined-subclass más debajo en la jerarquía de herencia.
+        </para>
+
+        <para>
+            Ten en cuenta que existen actualmente unas pocas limitaciones con las operaciones HQL masivas,
+            que serán atendidas en lanzamientos futuros; consulta la hoja de ruta de JIRA para más detalles.
+        </para>
+
+    </sect1>
+
+</chapter>

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/best_practices.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/best_practices.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/best_practices.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/best_practices.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,229 @@
+<chapter id="best-practices" revision="3">
+    <title>Mejores Pr&#x00e1;cticas</title>
+
+    <variablelist spacing="compact">
+        <varlistentry>
+            <term>Escribe clase finamente granularizadas y mapealas usando <literal>&lt;component&gt;</literal>.</term>
+            <listitem>
+                <para>
+                    Usa una clase <literal>Direcci&#x00f3;n</literal> para encapsular <literal>calle</literal>,
+                    <literal>distrito</literal>, <literal>estado</literal>, <literal>c&#x00f3;digo postal</literal>.
+                    Esto alienta la reutilizaci&#x00f3;n de c&#x00f3;digo y simplifica el refactoring.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Declara las propiedades identificadoras en clases persistentes.</term>
+            <listitem>
+                <para>
+                    Hibernate hace opcionales las propiedades identificadoras. Existen todo tipo de razones
+                    por las que debes usarlas. Recomendamos que los identificadores sean 'sint&#x00e9;ticos'
+                    (generados, sin ning&#x00fa;n significado de negocio).
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Identifica las claves naturales.</term>
+            <listitem>
+                <para>
+                    Identifica las claves naturales de todas las entidades, y mapealas usando
+                    <literal>&lt;natural-id&gt;</literal>. Implementa <literal>equals()</literal> y
+                    <literal>hashCode()</literal> para comparar las propiedades que componen la clave natural.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Coloca cada mapeo de clase en su propio fichero.</term>
+            <listitem>
+                <para>
+                     No uses un solo documento monol&#x00ed;tico de mapeo. Mapea <literal>com.eg.Foo</literal> en
+                     el fichero <literal>com/eg/Foo.hbm.xml</literal>. Esto tiene sentido particularmente en un
+                     ambiente de equipo.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Carga los mapeos como recursos.</term>
+            <listitem>
+                <para>
+                    Despliega los mapeos junto a las clases que mapean.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Considera externalizar las cadenas de consulta.</term>
+            <listitem>
+                <para>
+                    Esta es una buena pr&#x00e1;ctica si tus consultas llaman a funciones SQL que no son del
+                    est&#x00e1;ndar ANSI. Externalizar las cadenas de consulta a ficheros de mapeo har&#x00e1; la
+                    aplicaci&#x00f3;n m&#x00e1;s portable.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Usa variables de ligado.</term>
+            <listitem>
+                <para>
+                     Igual que en JDBC, siempre remplaza valores no constantes con "?". &#x00a1;Nunca uses manipulaci&#x00f3;n
+                     de cadenas para ligar un valor no constante en una consulta! Incluso mejor, considera usar
+                     par&#x00e1;metros con nombre en las consultas.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>No manejes tus propias conexiones JDBC.</term>
+            <listitem>
+                <para>
+                    Hibernate deja a la aplicaci&#x00f3;n administre las conexiones JDBC. Este enfoque debe considerarse
+                    como &#x00fa;ltimo recurso. Si no puedes usar los provedores de conexi&#x00f3;n prefabricados, considera
+                    prover tu propia implementaci&#x00f3;n de <literal>org.hibernate.connection.ConnectionProvider</literal>.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Considera usar un tipo personalizado.</term>
+            <listitem>
+                <para>
+                    Sup&#x00f3;n que tienes un tipo Java, digamos de alguna biblioteca, que necesita hacerse persistente
+                    pero no provee los m&#x00e9;todos de acceso necesarios para mapearlo como un componente. Debes considerar
+                    implementar <literal>org.hibernate.UserType</literal>. Este enfoque libera al c&#x00f3;digo de aplicaci&#x00f3;n
+                    de implementar transformaciones a / desde un tipo Hibernate.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Usa JDBC codificado a mano en cuellos de botella.</term>
+            <listitem>
+                <para>
+                    En &#x00e1;reas del sistema de rendimiento cr&#x00ed;tico, algunos tipos de operaciones podr&#x00ed;an beneficiarse
+                    del JDBC directo. Pero por favor, espero hasta que <emphasis>sepas</emphasis> que algo es
+                    un cuello de botella. Y no asumas que el JDBC directo es necesariamente m&#x00e1;s r&#x00e1;pido. Si necesitas
+                    usar JDBC directo, podr&#x00ed;a ser valioso abrir una <literal>Session</literal> de Hibernate y usar esa
+                    conexi&#x00f3;n JDBC. De esta forma puedes usar a&#x00fa;n la misma estrategia de transacci&#x00f3;n y el mismo
+                    proveedor de conexiones subyacente.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Comprende la limpieza (flushing) de <literal>Session</literal>.</term>
+            <listitem>
+                <para>
+                    De vez en cuando la sesi&#x00f3;n sincroniza su estado persistente con la base de datos. El rendimiento
+                    se ver&#x00e1; afectado si este proceso ocurre demasiado frecuentemente. A veces puedes minimizar
+                    limpieza innecesaria deshabilitando la limpieza autom&#x00e1;tica o incluso cambiando el orden de las
+                    consultas u otras operaciones en una transacci&#x00f3;n en particular.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>En una aplicaci&#x00f3;n en tres gradas, considera usar objetos separados.</term>
+            <listitem>
+                <para>
+                    Al usar una arquitectura de servlet / sesi&#x00f3;n, puedes pasar objetos persistentes en el bean de
+                    sesi&#x00f3;n hacia y desde la capa de servlet / JSP. Usa una sesi&#x00f3;n nueva para atender el servicio de cada
+                    petici&#x00f3;n. Usa <literal>Session.merge()</literal> o <literal>Session.saveOrUpdate()</literal> para
+                    sincronizar los objetos con la base de datos.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>En una arquitectura en dos gradas, considera usar contexto de persistencia largos.</term>
+            <listitem>
+                <para>
+                    Las transacciones de base de datos tienen que ser tan cortas como sea posible. Sin embargo,
+                    frecuentemente es necesario implementar <emphasis>transacciones de aplicaci&#x00f3;n</emphasis>
+                    ejecut&#x00e1;ndose en largo, una sola unidad de trabajo desde el punto de vista de un usuario.
+                    Una transacci&#x00f3;n de aplicaci&#x00f3;n puede abarcar muchos ciclos petici&#x00f3;n/respuesta del cliente.
+                    Es com&#x00fa;n usar objetos separados para implementar transacciones de aplicaci&#x00f3;n. Una alternativa,
+                    extremadamente apropiada en arquitecturas en dos gradas, es mantener un solo contacto de persistencia
+                    abierto (sesi&#x00f3;n) para todo el ciclo de vida de la transacci&#x00f3;n de aplicaci&#x00f3;n y simplemente
+                    desconectar de la conexi&#x00f3;n JDBC al final de cada petici&#x00f3;n, y reconectar al comienzo de la
+                    petici&#x00f3;n subsecuente. Nunca compartas una &#x00fa;nica sesi&#x00f3;n a trav&#x00e9;s de m&#x00e1;s de una transacci&#x00f3;n
+                    de aplicaci&#x00f3;n, o estar&#x00e1;s trabajando con datos añejos.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>No trates la excepciones como recuperables.</term>
+            <listitem>
+                <para>
+                    Esto es m&#x00e1;s una pr&#x00e1;ctica necesaria que una "mejor" pr&#x00e1;ctica. Cuando ocurra una excepci&#x00f3;n,
+                    deshaz (rollback) la <literal>Transaction</literal> y cierra la <literal>Session</literal>.
+                    Si no lo haces, Hibernate no puede garantizar que el estado en memoria representa con exactitud
+                    el estado persistente. Como un caso especial de esto, no uses <literal>Session.load()</literal>
+                    para determinar si una instancia con el identificador dado existe en la base de datos. En cambio,
+                    usa <literal>Session.get()</literal> o una consulta.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Prefiere la recuperaci&#x00f3;n perezosa para las asociaciones.</term>
+            <listitem>
+                <para>
+                    Usa escasamente la recuperaci&#x00f3;n temprana. Usa proxies y colecciones perezosas para la mayor&#x00ed;a
+                    de asociaciones a clases probablemente no est&#x00e9;n mantenidas en el cach&#x00e9; de segundo nivel. Para
+                    las asociaciones a clases en cach&#x00e9;, donde hay una probabilidad de acceso a cach&#x00e9; extremadamente
+                    alta, deshabilita expl&#x00ed;citamente la recuperaci&#x00f3;n temprana usando <literal>lazy="false"</literal>.
+                    Cuando sea apropiada la recuperaci&#x00f3;n por uni&#x00f3;n (join fetching) para un caso de uso en particular,
+                    usa una consulta con un <literal>left join fetch</literal>.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>
+                Usa el patr&#x00f3;n <emphasis>sesi&#x00f3;n abierta en vista</emphasis>, o una <emphasis>fase de ensamblado</emphasis>
+                disciplinada para evitar problemas con datos no recuperados.
+            </term>
+            <listitem>
+                <para>
+                    Hibernate liberal al desarrollador de escribir <emphasis>Objetos de Transferencia de Datos
+                    (Data Transfer Objects)</emphasis> (DTO). En una arquitectura tradicional de EJB, los DTOs tienen
+                    un prop&#x00f3;sito doble: primero, atacan el problema que los beans de entidad no son serializables.
+                    Segundo, definen impl&#x00ed;citamente una fase de ensamblado cuando se recuperan y se forman (marshalling)
+                    todos los datos a usar por la vista en los DTOs antes de devolver el control a la grada de
+                    presentaci&#x00f3;n. Hibernate elimina el primer prop&#x00f3;sito. Sin embargo, a&#x00fa;n necesitas una fase
+                    de ensamblado (piensa en tus m&#x00e9;todos de negocio como si tuviesen un contrato estricto con la grada
+                    de presentaci&#x00f3;n sobre qu&#x00e9; datos est&#x00e1;n disponibles en los objetos separados) a menos que est&#x00e9;s
+                    preparado para tener el contexto de persistencia (la sesi&#x00f3;n) abierto a trav&#x00e9;s del proceso
+                    de renderizaci&#x00f3;n de la vista. &#x00a1;Esta no es una limitaci&#x00f3;n de Hibernate! Es un requerimiento
+                    fundamental de acceso seguro a datos transaccionales.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Considera abstraer tu l&#x00f3;gica de negocio de Hibernate</term>
+            <listitem>
+                <para>
+                    Oculta el c&#x00f3;digo de acceso a datos (Hibernate) detr&#x00e1;s de una interface. Combina los patrones
+                    <emphasis>DAO</emphasis> y <emphasis>Sesi&#x00f3;n de Hebra Local</emphasis>. Incluso puedes tener
+                    algunas clases hechas persistentes por JDBC escrito a mano, asociadas a Hibernate por medio
+                    de un <literal>UserType</literal>. (Este consejo est&#x00e1; pensado para aplicaciones "suficientemente
+                    grandes"; &#x00a1;no es apropiado para una aplicaci&#x00f3;n con cinco tablas!)
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>No uses mapeos de asociaci&#x00f3;n ex&#x00f3;ticos.</term>
+            <listitem>
+                <para>
+                    Son raros los casos de uso de asociaciones reales muchos-a-muchos. La mayor parte del tiempo
+                    necesitas informaci&#x00f3;n adicional almacenada en una "tabla de enlace". En este caso, es mucho
+                    mejor usar dos asociaciones uno-a-muchos a una clase de enlace intermedia. De hecho, pensamos
+                    que la mayor&#x00ed;a de asociaciones son uno-a-muchos y muchos-a-uno, debes ser cuidadoso al usr
+                    cualquier otro estilo de asociaci&#x00f3;n y preguntarte si es realmente necesario.
+                </para>
+            </listitem>
+        </varlistentry>
+        <varlistentry>
+            <term>Prefiere las asociaciones bidireccionales.</term>
+            <listitem>
+                <para>
+                    Las asociaciones unidireccionales son m&#x00e1;s dif&#x00ed;ciles de consultar. En una aplicaci&#x00f3;n grande,
+                    casi todas las asociaciones deben ser navegables en ambas direcciones en consultas.
+                </para>
+            </listitem>
+        </varlistentry>
+    </variablelist>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/collection_mapping.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/collection_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/collection_mapping.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/collection_mapping.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,1241 @@
+<chapter id="collections">
+    <title>Mapeo de Colecciones</title>
+
+    <sect1 id="collections-persistent" revision="3">
+        <title>Colecciones persistentes</title>
+        
+        <para>
+            Hibernate requiere que los campos valuados en colecci&#x00f3;n
+            persistentes sean declarados como un tipo de interface, por ejemplo:
+        </para>
+        
+        <programlisting><![CDATA[public class Product {
+    private String serialNumber;
+    private Set parts = new HashSet();
+    
+    public Set getParts() { return parts; }
+    void setParts(Set parts) { this.parts = parts; }
+    public String getSerialNumber() { return serialNumber; }
+    void setSerialNumber(String sn) { serialNumber = sn; }
+}]]></programlisting>
+        
+        <para>
+            La interface real podr&#x00ed;a ser <literal>java.util.Set</literal>,
+            <literal>java.util.Collection</literal>, <literal>java.util.List</literal>,
+            <literal>java.util.Map</literal>, <literal>java.util.SortedSet</literal>,
+            <literal>java.util.SortedMap</literal> o ... lo que te guste!
+            (Donde "lo que te guste" significa que tendr&#x00e1;s que escribir una
+            implementaci&#x00f3;n de <literal>org.hibernate.usertype.UserCollectionType</literal>.)
+        </para>
+        
+        <para>
+            Nota c&#x00f3;mo hemos inicializado la variable de instancia de
+            <literal>HashSet</literal>. Esta es la mejor forma de inicializar
+            propiedades valuadas en colecci&#x00f3;n de instancias reci&#x00e9;n
+            instanciadas (no persistentes). Cuando haces persistente la instancia
+            - llamando a <literal>persist()</literal>, por ejemplo - Hibernate realmente
+            remplazar&#x00e1; el <literal>HashSet</literal> con una instancia de una
+            implementaci&#x00f3;n de <literal>Set</literal> propia de Hibernate.
+             Observa errores como este:
+        </para>
+        
+        <programlisting><![CDATA[Cat cat = new DomesticCat();
+Cat kitten = new DomesticCat();
+....
+Set kittens = new HashSet();
+kittens.add(kitten);
+cat.setKittens(kittens);
+session.persist(cat);
+kittens = cat.getKittens(); // Okay, kittens collection is a Set
+(HashSet) cat.getKittens(); // Error!]]></programlisting>
+
+        <para>
+            Las colecciones persistentes inyectadas por Hibernate se comportan
+            como <literal>HashMap</literal>, <literal>HashSet</literal>,
+            <literal>TreeMap</literal>, <literal>TreeSet</literal> o
+            <literal>ArrayList</literal>, dependiendo del tipo de interface.
+        </para>
+
+        <para>
+            Las instancias de colecciones tienen el comportamiento usual de tipos de valor.
+            Son autom&#x00e1;ticamente persistidas al ser referenciadas por un objeto
+            persistente y autom&#x00e1;ticamente borradas al desreferenciarse. Si una
+            colecci&#x00f3;n es pasada de un objeto persistente a otro, sus elementos
+            ser&#x00ed;an movidos de una tabla a otra. Dos entidades pueden no
+            compartir una referencia a la misma instancia de colecci&#x00f3;n.
+            Debido al modelo relacional subyacente, las propiedades valuadas en
+            colecci&#x00f3;n no soportan la sem&#x00e1;ntica de valor nulo. Hibernate no
+            distingue entre una referencia de colecci&#x00f3;n nula y una colecci&#x00f3;n
+            vac&#x00ed;a.
+        </para>
+
+        <para>
+            No debes tener que preocuparte demasiado por esto. Usa las colecciones
+            persistentes de la misma forma en que usas colecciones de Java ordinarias.
+            S&#x00f3;lo aseg&#x00fa;rate que entiendes la sem&#x00e1;ntica de las asociaciones
+            bidireccionales (discutida luego).
+        </para>
+
+    </sect1>
+
+    <sect1 id="collections-mapping" revision="2">
+        <title>Mapeos de colecci&#x00f3;n</title>
+
+        <para>
+            El elemento de mapeo de Hibernate usado para mapear una colecci&#x00f3;n
+            depende del tipo de la interface. Por ejemplom un elemento
+            <literal>&lt;set&gt;</literal> se usa para mapear propiedades de tipo
+            <literal>Set</literal>.
+        </para>
+        
+        <programlisting><![CDATA[<class name="Product">
+    <id name="serialNumber" column="productSerialNumber"/>
+    <set name="parts">
+        <key column="productSerialNumber" not-null="true"/>
+        <one-to-many class="Part"/>
+    </set>
+</class>]]></programlisting>
+
+        <para>
+            Aparte de <literal>&lt;set&gt;</literal>, existen adem&#x00e1;s
+            los elementos de mapeo <literal>&lt;list&gt;</literal>,
+            <literal>&lt;map&gt;</literal>, <literal>&lt;bag&gt;</literal>,
+            <literal>&lt;array&gt;</literal> y <literal>&lt;primitive-array&gt;</literal>.
+            El elemento <literal>&lt;map&gt;</literal> es representativo:
+        </para>
+
+        <programlistingco>
+            <areaspec>
+                <area id="mappingcollection1" coords="2 65"/>
+                <area id="mappingcollection2" coords="3 65"/>
+                <area id="mappingcollection3" coords="4 65"/>
+                <area id="mappingcollection4" coords="5 65"/>
+                <area id="mappingcollection5" coords="6 65"/>
+                <area id="mappingcollection6" coords="7 65"/>
+                <area id="mappingcollection7" coords="8 65"/>
+                <area id="mappingcollection8" coords="9 65"/>
+                <area id="mappingcollection9" coords="10 65"/>
+                <area id="mappingcollection10" coords="11 65"/>
+                <area id="mappingcollection11" coords="12 65"/>
+                <area id="mappingcollection12" coords="13 65"/>
+                <area id="mappingcollection13" coords="14 65"/>
+            </areaspec>
+            <programlisting><![CDATA[<map
+    name="propertyName"
+    table="table_name"
+    schema="schema_name"
+    lazy="true|false"
+    inverse="true|false"
+    cascade="all|none|save-update|delete|all-delete-orphan"
+    sort="unsorted|natural|comparatorClass"
+    order-by="column_name asc|desc"
+    where="arbitrary sql where condition"
+    fetch="join|select|subselect"
+    batch-size="N"
+    access="field|property|ClassName"
+    optimistic-lock="true|false"
+    node="element-name|."
+    embed-xml="true|false"
+>
+
+    <key .... />
+    <map-key .... />
+    <element .... />
+</map>]]></programlisting>
+            <calloutlist>
+                <callout arearefs="mappingcollection1">
+                    <para>
+                        <literal>name</literal> el nombre de la propiedad de colecci&#x00f3;n
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection2">
+                    <para>
+                        <literal>table</literal> (opcional - por defecto al nombre de la propiedad)
+                        el nombre de la tabla de colecii&#x00f3;n (no usado para asociaciones
+                        uno-a-muchos)
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection3">
+                    <para>
+                        <literal>schema</literal> (opcional) el nombre de un esquema de tablas
+                        para sobrescribir el esquema declarado en el elemento ra&#x00ed;z
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection4">
+                    <para>
+                        <literal>lazy</literal> (opcional - por defecto a <literal>true</literal>)
+                        puede ser usado para deshabilitar la recuperaci&#x00f3;n perezosa y
+                        especificar que la asociaci&#x00f3;n es siempre recuperada tempranamente
+                        (no disponible para arrays)
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection5">
+                    <para>
+                        <literal>inverse</literal> (opcional - por defecto a <literal>false</literal>)
+                        marca esta colecci&#x00f3;n como el extremo "inverso" de una asociaci&#x00f3;n
+                        bidireccional.
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection6">
+                    <para>
+                        <literal>cascade</literal> (opcional - por defecto a <literal>none</literal>)
+                        habilita operaciones en cascada a entidades hijas
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection7">
+                    <para>
+                        <literal>sort</literal> (opcional) especifica una colecci&#x00f3;n
+                        con ordenamiento <literal>natural</literal>, o una clase comparadora
+                        dada
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection8">
+                    <para>
+                        <literal>order-by</literal> (opcional, s&#x00f3;lo JDK1.4) especifica una columna
+                        de tabla (o columnas) que definen el orden de iteraci&#x00f3;n del
+                        <literal>Map</literal>, <literal>Set</literal> o bag, junto a un
+                        <literal>asc</literal> o <literal>desc</literal> opcional.
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection9">
+                    <para>
+                        <literal>where</literal> (opcional) especifica una condici&#x00f3;n
+                        <literal>WHERE</literal> de SQL arbitrario para ser usada al recuperar o
+                        quitar la colecci&#x00f3;n (&#x00fa;til si la colecci&#x00f3;n debe
+                        contener s&#x00f3;lo un subconjunto de los datos disponibles)
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection10">
+                    <para>
+                        <literal>fetch</literal> (opcional, por defecto a <literal>select</literal>)
+                        Elige entre recuperaci&#x00f3;n por uni&#x00f3;n externa (outer-join),
+                        recuperar por selecci&#x00f3;n secuencial, y recuperaci&#x00f3;n por
+                        subselecci&#x00f3;n secuencial.
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection11">
+                    <para>
+                        <literal>batch-size</literal> (opcional, por defecto a <literal>1</literal>)
+                        especifica un "tama&#x00f1;o de lote" para la recuperar
+                        perezosamente instancias de esta colecci&#x00f3;n.
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection12">
+                    <para>
+                        <literal>access</literal> (opcional - por defecto a <literal>property</literal>):
+                        La estrategia que debe usar Hibernate para acceder al valor de la
+                        propiedad.
+                    </para>
+                </callout>
+                <callout arearefs="mappingcollection12">
+                    <para>
+                        <literal>optimistic-lock</literal> (opcional - por defecto a <literal>true</literal>):
+                        Especifica que los cambios de estado de la colecci&#x00f3;n resultan en
+                        incrementos de versi&#x00f3;n de la entidad due&#x00f1;a. (Para asociaciones
+                        uno a muchos, frecuentemente es razonable deshabilitar esta opci&#x00f3;n.)
+                    </para>
+                </callout>
+            </calloutlist>
+        </programlistingco>
+
+        <sect2 id="collections-foreignkeys" >
+           <title>Claves for&#x00e1;neas de collecci&#x00f3;n</title>
+    
+            <para>
+                Las instancias de colecci&#x00f3;n se distinguen en la base de datos por la
+                clave for&#x00e1;nea de la entidad que posee la colecci&#x00f3;n. Se hace
+                referencia a esta clave for&#x00e1;nea como la <emphasis>columna clave de
+                colecci&#x00f3;n</emphasis> (o columnas) de la tabla de colecci&#x00f3;n.
+                La columna clave de la colecci&#x00f3;n es mapeada por el elemento
+                <literal>&lt;key&gt;</literal>.
+            </para>
+    
+            <para>
+                Puede haber una restricci&#x00f3;n de nulabilidad sobre la columna de clave
+                for&#x00e1;nea. Para la mayor&#x00ed;a de colecciones, esto est&#x00e1; implicado.
+                Para asociaciones unidireccionales uno a muchos, la columna de clave
+                for&#x00e1;nea es nulable por defecto, de modo que podr&#x00ed;as necesitar
+                especificar <literal>not-null="true"</literal>.
+            </para>
+    
+            <programlisting><![CDATA[<key column="productSerialNumber" not-null="true"/>]]></programlisting>
+    
+            <para>
+                La restricci&#x00f3;n de clave for&#x00e1;nea puede usar
+                <literal>ON DELETE CASCADE</literal>.
+            </para>
+    
+            <programlisting><![CDATA[<key column="productSerialNumber" on-delete="cascade"/>]]></programlisting>
+            
+            <para>
+                Mira el cap&#x00ed;tulo anterior por una definici&#x00f3;n completa del
+                elemento <literal>&lt;key&gt;</literal>.
+            </para>
+            
+        </sect2>
+        
+        <sect2 id="collections-elements" >
+            <title>Elementos de collecci&#x00f3;n</title>
+    
+            <para>
+                Las colecciones pueden contener casi cualquier tipo de Hibernate, incluyendo
+                todos los tipos b&#x00e1;sicos, componentes, y por supuesto, referencias a otras
+                entidades. Esta es una distinci&#x00f3;n importante: un objeto en una colecci&#x00f3;n
+                puede ser manejado con una sem&#x00e1;ntica de "valor" (su ciclo de vida depende
+                completamente del propietario de la colecci&#x00f3;n) o podr&#x00ed;a ser una referencia
+                a otra entidad, con su propio ciclo de vida. En el &#x00fa;ltimo caso, s&#x00f3;lo
+                el estado del "enlace" entre los dos objetos se considera mantenido por la
+                colecci&#x00f3;n.
+            </para>
+                
+            <para>
+                Se hace referencia al tipo contenido como el <emphasis>tipo de elemento
+                de la colecci&#x00f3;n</emphasis>. Los elementos de colecci&#x00f3;n son
+                mapeados por <literal>&lt;element&gt;</literal> o
+                <literal>&lt;composite-element&gt;</literal>, o en el caso de referencias
+                de entidades, con <literal>&lt;one-to-many&gt;</literal> o
+                <literal>&lt;many-to-many&gt;</literal>. Las dos primeras mapean elementos
+                con sem&#x00e1;ntica de valor, los dos siguientes son usados para mapear
+                asociaciones de entidades.
+            </para>
+            
+        </sect2>
+        
+        <sect2 id="collections-indexed">
+            <title>Colecciones indexadas</title>
+    
+            <para>
+                Todos los mapeos de colecci&#x00f3;n, excepto aquellos con sem&#x00e1;ntica de
+                set o bag, necesitan una <emphasis>columna &#x00ed;ndice</emphasis> en la tabla
+                de colecci&#x00f3;n, una columna que mapea a un &#x00ed;ndice de array, o
+                &#x00ed;ndice de <literal>List</literal>, o clave de <literal>Map</literal>.
+                El &#x00ed;ndice de un <literal>Map</literal> puede ser de cualquier tipo
+                b&#x00e1;sico, mapeado con <literal>&lt;map-key&gt;</literal>, o puede ser
+                una referencia de entidad, mapeada con <literal>&lt;map-key-many-to-many&gt;</literal>,
+                o puede ser un tipo compuesto, mapeado con <literal>&lt;composite-map-key&gt;</literal>.
+                El &#x00ed;ndice de un array o lista es siempre de tipo <literal>integer</literal>
+                y se mapea usando el elemento <literal>&lt;list-index&gt;</literal>. La columna
+                mapeada contiene enteros secuenciales (numerados desde cero, por defecto).
+            </para>
+
+        <programlistingco>
+            <areaspec>
+                <area id="index1" coords="2 45"/>
+                <area id="index2" coords="3 45"/>
+             </areaspec>
+            <programlisting><![CDATA[<list-index 
+        column="column_name"
+        base="0|1|..."/>]]></programlisting>
+            <calloutlist>
+                <callout arearefs="index1">
+                    <para>
+                        <literal>column_name</literal> (requerido): El nombre de la columna que tiene
+                        los valores &#x00ed;ndice de la colecci&#x00f3;n.
+                    </para>
+                </callout>
+                <callout arearefs="index1">
+                    <para>
+                        <literal>base</literal> (opcional, por defecto a <literal>0</literal>): El valor
+                        de la columna &#x00ed;ndice que corresponde al primer elemento de la lista o
+                        array.
+                    </para>
+                </callout>
+            </calloutlist>
+        </programlistingco>
+
+        <programlistingco>
+            <areaspec>
+                <area id="mapkey1" coords="2 45"/>
+                <area id="mapkey2" coords="3 45"/>
+                <area id="mapkey3" coords="4 45"/>
+             </areaspec>
+            <programlisting><![CDATA[<map-key 
+        column="column_name"
+        formula="any SQL expression"
+        type="type_name"
+        node="@attribute-name"
+        length="N"/>]]></programlisting>
+            <calloutlist>
+                <callout arearefs="mapkey1">
+                    <para>
+                        <literal>column</literal> (opcional): El nombre de la columna que tiene
+                        los valores &#x00ed;ndice de la colecci&#x00f3;n.
+                    </para>
+                </callout>
+                <callout arearefs="mapkey2">
+                    <para>
+                        <literal>formula</literal> (opcional): Una f&#x00f3;rmula SQL usada para
+                        evaluar la clave del mapa.
+                    </para>
+                </callout>
+                <callout arearefs="mapkey3">
+                    <para>
+                        <literal>type</literal> (requerido): el tipo de las claves del mapa.
+                    </para>
+                </callout>
+            </calloutlist>
+        </programlistingco>
+
+        <programlistingco>
+            <areaspec>
+                <area id="indexmanytomany1" coords="2 45"/>
+                <area id="indexmanytomany2" coords="3 45"/>
+                <area id="indexmanytomany3" coords="3 45"/>
+             </areaspec>
+            <programlisting><![CDATA[<map-key-many-to-many
+        column="column_name"
+        formula="any SQL expression"
+        class="ClassName"
+/>]]></programlisting>
+            <calloutlist>
+                <callout arearefs="indexmanytomany1">
+                    <para>
+                        <literal>column</literal> (opcional): El nombre de la columna clave
+                        for&#x00e1;nea para los valores &#x00ed;ndice de la colecci&#x00f3;n.
+                    </para>
+                </callout>
+                <callout arearefs="indexmanytomany2">
+                    <para>
+                        <literal>formula</literal> (opcional): Una f&#x00f3;rmula SQL usada para
+                        evaluar la clave for&#x00e1;nea de la clave del mapa.
+                    </para>
+                </callout>
+                <callout arearefs="indexmanytomany3">
+                    <para>
+                        <literal>class</literal> (requerido): La clase de entidad usada como clave del mapa.
+                    </para>
+                </callout>
+            </calloutlist>
+        </programlistingco>
+
+
+            <para>
+                Si tu tabla no tiene una columna &#x00ed;ndice, y deseas a&#x00fa;n usar <literal>List</literal> como
+                tipo de propiedad, debes mapear la propiedad como un <emphasis>&lt;bag&gt;</emphasis>
+                de Hibernate. Un bag (bolsa) no retiene su orden al ser recuperado de la base de datos,
+                pero puede ser ordenado o clasificado opcionalmente.
+            </para>
+            
+        </sect2>
+
+        <para>
+            Hay absolutamente un rango de mapeos que pueden ser generados para colecciones,
+            cubriendo muchos modelos relacionales comunes. Te sugerimos que experimentes con
+            la herramienta de generaci&#x00f3;n de esquemas para obtener una idea de c&#x00f3;mo varias
+            declaraciones de mapeo se traducen a tablas de base de datos.
+        </para>
+
+    <sect2 id="collections-ofvalues" revision="1">
+        <title>Colecciones de valores y asociaciones muchos-a-muchos</title>
+
+        <para>
+            Cualquier colecci&#x00f3;n de valores o asociaci&#x00f3;n muchos a muchos requiere una
+            <emphasis>tabla de colecci&#x00f3;n</emphasis> dedicada con una columna o columnas
+            de clave for&#x00e1;nea, <emphasis>columna de elemento de colecci&#x00f3;n</emphasis> o
+            columnas y posiblemente una columna o columnas &#x00ed;ndice.
+        </para>
+
+        <para>
+            Para una colecci&#x00f3;n de valores, usamos la etiqueta <literal>&lt;element&gt;</literal>.
+        </para>
+
+        <programlistingco>
+            <areaspec>
+                <area id="element1b" coords="2 50"/>
+                <area id="element2b" coords="3 50"/>
+                <area id="element3b" coords="4 50"/>
+             </areaspec>
+            <programlisting><![CDATA[<element
+        column="column_name"
+        formula="any SQL expression"
+        type="typename"
+        length="L"
+        precision="P"
+        scale="S"
+        not-null="true|false"
+        unique="true|false"
+        node="element-name"
+/>]]></programlisting>
+            <calloutlist>
+                <callout arearefs="element1b">
+                    <para>
+                        <literal>column</literal> (opcional): El nombre de la columna que tiene
+                        los valores de los elementos de la colecci&#x00f3;n.
+                    </para>
+                </callout>
+                <callout arearefs="element2b">
+                    <para>
+                        <literal>formula</literal> (opcional): Una f&#x00f3;rmula SQL usada para evaluar
+                        el elemento.
+                    </para>
+                </callout>
+                <callout arearefs="element3b">
+                    <para>
+                        <literal>type</literal> (requerido): El tipo del elemento de colecci&#x00f3;n.
+                    </para>
+                </callout>
+            </calloutlist>
+        </programlistingco>
+
+        <para>
+            Una <emphasis>asociaci&#x00f3;n muchos-a-muchos</emphasis> se especifica usando
+            el elemento <literal>&lt;many-to-many&gt;</literal>.
+        </para>
+
+        <programlistingco>
+            <areaspec>
+                <area id="manytomany1" coords="2 60"/>
+                <area id="manytomany2" coords="3 60"/>
+                <area id="manytomany3" coords="4 60"/>
+                <area id="manytomany4" coords="5 60"/>
+                <area id="manytomany5" coords="6 60"/>
+                <area id="manytomany6" coords="7 60"/>
+                <area id="manytomany7" coords="8 60"/>
+            </areaspec>
+            <programlisting><![CDATA[<many-to-many
+        column="column_name"
+        formula="any SQL expression"
+        class="ClassName"
+        fetch="select|join"
+        unique="true|false"
+        not-found="ignore|exception"
+        entity-name="EntityName"
+        node="element-name"
+        embed-xml="true|false"
+    />]]></programlisting>
+            <calloutlist>
+                <callout arearefs="manytomany1">
+                    <para>
+                        <literal>column</literal> (opcional): El nombre de la columna de clave
+                        for&#x00e1;nea del elemento.
+                    </para>
+                </callout>
+                <callout arearefs="manytomany2">
+                    <para>
+                        <literal>formula</literal> (opcional): Una f&#x00f3;rmula SQL opcional usada
+                        para evaluar el valor de clave for&#x00e1;nea del elemento.
+                    </para>
+                </callout>
+                <callout arearefs="manytomany3">
+                    <para>
+                        <literal>class</literal> (requerido): El nombre de la clase asociada.
+                    </para>
+                </callout>
+                <callout arearefs="manytomany4">
+                    <para>
+                        <literal>fetch</literal> (opcional - por defecto a <literal>join</literal>):
+                        habilita la recuperaci&#x00f3;n por uni&#x00f3;n externa o selecci&#x00f3;n secuencial para esta
+                        asociaci&#x00f3;n. Este es un caso especial; para una recuperaci&#x00f3;n completamente
+                        temprana (en un solo <literal>SELECT</literal>) de una entidad y sus relaciones
+                        muchos-a-muchos a otras entidades, deber&#x00ed;as habilitar la recuperaci&#x00f3;n
+                        <literal>join</literal> no s&#x00f3;lo de la colecci&#x00f3;n misma, sino tambi&#x00e9;n con este
+                        atributo en el elemento anidado <literal>&lt;many-to-many&gt;</literal>.
+                    </para>
+                </callout>
+                <callout arearefs="manytomany5">
+                    <para>
+                        <literal>unique</literal> (opcional): Habilita la generaci&#x00f3;n DDL de una
+                        restricci&#x00f3;n de unicidad para la columna clave for&#x00e1;nea. Esto hace la
+                        multiplicidad de la asociaci&#x00f3;n efectivamente uno a muchos.
+                    </para>
+                </callout>
+	            <callout arearefs="manytomany6">
+	                <para>
+	                    <literal>not-found</literal> (opcional - por defecto a <literal>exception</literal>): 
+                            Especifica c&#x00f3;mo ser&#x00e1;n manejadas las claves for&#x00e1;neas que referencian
+                            filas perdidas: <literal>ignore</literal> tratar&#x00e1; una fila perdida como
+                            una asociaci&#x00f3;n nula.
+	                </para>
+	            </callout>
+                <callout arearefs="manytomany7">
+                    <para>
+                        <literal>entity-name</literal> (opcional): El nombre de entidad de la clase
+                        asociada, como una alternativa a <literal>class</literal>.
+                    </para>
+                </callout>
+            </calloutlist>
+        </programlistingco>
+
+        <para>
+            Algunos ejemplos, primero, un conjunto de cadenas:
+        </para>
+
+        <programlisting><![CDATA[<set name="names" table="person_names">
+    <key column="person_id"/>
+    <element column="person_name" type="string"/>
+</set>]]></programlisting>
+
+        <para>
+            Un bag conteniendo enteros (con un orden de iteraci&#x00f3;n determinado por el
+            atributo <literal>order-by</literal>):
+        </para>
+
+        <programlisting><![CDATA[<bag name="sizes" 
+        table="item_sizes" 
+        order-by="size asc">
+    <key column="item_id"/>
+    <element column="size" type="integer"/>
+</bag>]]></programlisting>
+
+        <para>
+            Un array de entidades - en este caso, una asociaci&#x00f3;n muchos a muchos:
+        </para>
+
+        <programlisting><![CDATA[<array name="addresses" 
+        table="PersonAddress" 
+        cascade="persist">
+    <key column="personId"/>
+    <list-index column="sortOrder"/>
+    <many-to-many column="addressId" class="Address"/>
+</array>]]></programlisting>
+
+        <para>
+            Un mapa de &#x00ed;ndices de cadenas a fechas:
+        </para>
+
+        <programlisting><![CDATA[<map name="holidays" 
+        table="holidays" 
+        schema="dbo" 
+        order-by="hol_name asc">
+    <key column="id"/>
+    <map-key column="hol_name" type="string"/>
+    <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+        <para>
+            Una lista de componentes (discutidos en el pr&#x00f3;ximo cap&#x00ed;tulo):
+        </para>
+
+        <programlisting><![CDATA[<list name="carComponents" 
+        table="CarComponents">
+    <key column="carId"/>
+    <list-index column="sortOrder"/>
+    <composite-element class="CarComponent">
+        <property name="price"/>
+        <property name="type"/>
+        <property name="serialNumber" column="serialNum"/>
+    </composite-element>
+</list>]]></programlisting>
+
+    </sect2>
+
+    <sect2 id="collections-onetomany">
+        <title>Asociaciones uno-a-muchos</title>
+
+        <para>
+            Una <emphasis>asociaci&#x00f3;n uno a muchos</emphasis> enlaza las tablas de dos clases
+            por medio de una clave for&#x00e1;nea, sin intervenci&#x00f3;n de tabla de colecci&#x00f3;n alguna.
+            Este mapeo pierde cierta sem&#x00e1;ntica de colecciones Java normales:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    Una instancia de la clase entidad contenida no puede pertenecer
+                    a m&#x00e1;s de una instancia de la colecci&#x00f3;n.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Una instancia de la clase entidad contenida no puede aparecer en m&#x00e1;s
+                    de un valor del &#x00ed;ndice de colecci&#x00f3;n.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Una asociaci&#x00f3;n de <literal>Product</literal> a <literal>Part</literal> requiere la
+            existencia de una columna clave for&#x00e1;nea y posiblemente una columna &#x00ed;ndice a la tabla
+            <literal>Part</literal>. Una etiqueta <literal>&lt;one-to-many&gt;</literal> indica
+            que &#x00e9;sta es una asociaci&#x00f3;n uno a muchos.
+        </para>
+
+        <programlistingco>
+            <areaspec>
+                <area id="onetomany1" coords="2 60"/>
+                <area id="onetomany2" coords="3 60"/>
+                <area id="onetomany3" coords="4 60"/>
+            </areaspec>
+            <programlisting><![CDATA[<one-to-many 
+        class="ClassName"
+        not-found="ignore|exception"
+        entity-name="EntityName"
+        node="element-name"
+        embed-xml="true|false"
+    />]]></programlisting>
+            <calloutlist>
+                <callout arearefs="onetomany1">
+                    <para>
+                        <literal>class</literal> (requerido): El nombre de la clase asociada.
+                    </para>
+                </callout>
+		        <callout arearefs="onetomany2">
+		            <para>
+		                <literal>not-found</literal> (opcional - por defecto a <literal>exception</literal>): 
+                                Especifica c&#x00f3;mo ser&#x00e1;n manejados los identificadores en cach&#x00e9; que referencien
+                                filas perdidas: <literal>ignore</literal> tratar&#x00e1; una fila perdida como una
+                                asociaci&#x00f3;n nula.
+		            </para>
+		        </callout>
+                <callout arearefs="onetomany3">
+                    <para>
+                        <literal>entity-name</literal> (opcional): El nombre de entidad de la clase
+                        asociada, como una alternativa a <literal>class</literal>.
+                    </para>
+                </callout>
+            </calloutlist>
+       </programlistingco>
+  
+        <para>
+            Observa que el elemento <literal>&lt;one-to-many&gt;</literal> no necesita
+            declarar ninguna columna. Ni es necesario especificar el nombre de <literal>table</literal>
+            en ning&#x00fa;n sitio.
+        </para>
+
+        <para>
+            <emphasis>Nota muy importante:</emphasis> Si la columna clave for&#x00e1;nea de una asociaci&#x00f3;n
+            <literal>&lt;one-to-many&gt;</literal> es declarada <literal>NOT NULL</literal>, debes
+            declarar el mapeo de <literal>&lt;key&gt;</literal> <literal>not-null="true"</literal>
+            o <emphasis>usar una asociaci&#x00f3;n bidireccional</emphasis> con el mapeo de colecci&#x00f3;n
+            marcado <literal>inverse="true"</literal>. Ver la discusi&#x00f3;n sobre asociaciones
+            bidireccionales m&#x00e1;s adelante en este cap&#x00ed;tulo.
+        </para>
+        
+        <para>
+            Este ejemplo muestra un mapa de entidades <literal>Part</literal> por nombre
+            (donde <literal>partName</literal> es una propiedad persistente de <literal>Part</literal>).
+            Observa el uso de un &#x00ed;ndice basado en f&#x00f3;rmula.
+        </para>
+
+        <programlisting><![CDATA[<map name="parts"
+        cascade="all">
+    <key column="productId" not-null="true"/>
+    <map-key formula="partName"/>
+    <one-to-many class="Part"/>
+</map>]]></programlisting>
+    </sect2>
+    
+    </sect1>
+
+    <sect1 id="collections-advancedmappings">
+        <title>Mapeos de colecci&#x00f3;n avanzados</title>
+
+    <sect2 id="collections-sorted" revision="2">
+        <title>Colecciones ordenadas</title>
+
+        <para>
+            Hibernate soporta colecciones implementando <literal>java.util.SortedMap</literal> y
+            <literal>java.util.SortedSet</literal>. Debes especificar un comparador en el fichero de
+            mapeo:
+        </para>
+
+        <programlisting><![CDATA[<set name="aliases" 
+            table="person_aliases" 
+            sort="natural">
+    <key column="person"/>
+    <element column="name" type="string"/>
+</set>
+
+<map name="holidays" sort="my.custom.HolidayComparator">
+    <key column="year_id"/>
+    <map-key column="hol_name" type="string"/>
+    <element column="hol_date" type="date"/>
+</map>]]></programlisting>
+
+        <para>
+            Los valores permitidos del atributo <literal>sort</literal> son <literal>unsorted</literal>,
+            <literal>natural</literal> y el nombre de una clase que implemente
+            <literal>java.util.Comparator</literal>.
+        </para>
+
+        <para>
+            Las colecciones ordenadas realmente se comportan como <literal>java.util.TreeSet</literal> o
+            <literal>java.util.TreeMap</literal>.
+        </para>
+
+        <para>
+            Si quieres que la misma base de datos ordene los elementos de colecci&#x00f3;n usa el
+            atributo <literal>order-by</literal> de los mapeos <literal>set</literal>,
+            <literal>bag</literal> o <literal>map</literal>. Esta soluci&#x00f3;n est&#x00e1; disponible s&#x00f3;lo
+            bajo el JDK 1.4 o superior (est&#x00e1; implementado usando <literal>LinkedHashSet</literal> o
+            <literal>LinkedHashMap</literal>). Esto realiza la ordenaci&#x00f3;n en la consulta SQL,
+            no en memoria.
+        </para>
+
+        <programlisting><![CDATA[<set name="aliases" table="person_aliases" order-by="lower(name) asc">
+    <key column="person"/>
+    <element column="name" type="string"/>
+</set>
+
+<map name="holidays" order-by="hol_date, hol_name">
+    <key column="year_id"/>
+    <map-key column="hol_name" type="string"/>
+    <element column="hol_date type="date"/>
+</map>]]></programlisting>
+
+        <para>
+            Observa que el valor del atributo <literal>order-by</literal> es una ordenaci&#x00f3;n SQL, no
+            una ordenaci&#x00f3;n HQL!
+        </para>
+
+        <para>
+            Las asociaciones pueden incluso ser ordenadas por alg&#x00fa;n criterio arbitrario en tiempo de
+            ejecuci&#x00f3;n usando un <literal>filter()</literal> de colecci&#x00f3;n.
+        </para>
+
+        <programlisting><![CDATA[sortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list();]]></programlisting>
+
+    </sect2>
+
+     <sect2 id="collections-bidirectional" revision="1">
+        <title>Asociaciones bidireccionales</title>
+
+        <para>
+            Una <emphasis>asociaci&#x00f3;n bidireccional</emphasis> permite la nevegaci&#x00f3;n desde
+            ambos "extremos" de la asociaci&#x00f3;n. Son soportados dos tipos de asociaci&#x00f3;n
+            bidireccional:
+
+            <variablelist>
+                <varlistentry>
+                    <term>uno-a-muchos</term>
+                    <listitem>
+                        <para>
+                            set o bag valorados en un extremo, monovaluados al otro
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>muchos-a-muchos</term>
+                    <listitem>
+                        <para>
+                            set o bag valorados a ambos extremos
+                        </para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+
+        </para>
+
+        <para>
+            Puedes especificar una asociaci&#x00f3;n bidireccional muchos-a-muchos simplemente
+            mapeando dos asociaciones muchos-a-muchos a la misma tabla de base de datos
+            y declarando un extremo como <emphasis>inverse</emphasis> (cu&#x00e1;l de ellos es tu
+            elecci&#x00f3;n, pero no puede ser una colecci&#x00f3;n indexada).
+        </para>
+
+        <para>
+            He aqu&#x00ed; un ejemplo de una asociaci&#x00f3;n bidireccional muchos-a-muchos; cada categor&#x00ed;a
+            puede tener muchos &#x00ed;tems y cada &#x00ed;tem puede estar en muchas categor&#x00ed;as:
+        </para>
+
+        <programlisting><![CDATA[<class name="Category">
+    <id name="id" column="CATEGORY_ID"/>
+    ...
+    <bag name="items" table="CATEGORY_ITEM">
+        <key column="CATEGORY_ID"/>
+        <many-to-many class="Item" column="ITEM_ID"/>
+    </bag>
+</class>
+
+<class name="Item">
+    <id name="id" column="ITEM_ID"/>
+    ...
+
+    <!-- inverse end -->
+    <bag name="categories" table="CATEGORY_ITEM" inverse="true">
+        <key column="ITEM_ID"/>
+        <many-to-many class="Category" column="CATEGORY_ID"/>
+    </bag>
+</class>]]></programlisting>
+
+        <para>
+            Los cambios hechos s&#x00f3;lo al extremo inverso de la asociaci&#x00f3;n <emphasis>no</emphasis>
+            son persistidos. Esto significa que Hibernate tiene dos representaciones en memoria
+            para cada asociaci&#x00f3;n bidireccional, una enlaza de A a B y otra enlaza de B a A.
+            Esto es m&#x00e1;s f&#x00e1;cil de entender si piensas en el modelo de objetos de Java y c&#x00f3;mo
+            creamos una relaci&#x00f3;n muchos-a-muchos en Java:
+        </para>
+
+        <programlisting><![CDATA[
+category.getItems().add(item);          // The category now "knows" about the relationship
+item.getCategories().add(category);     // The item now "knows" about the relationship
+
+session.persist(item);                   // The relationship won't be saved!
+session.persist(category);               // The relationship will be saved]]></programlisting>
+
+        <para>
+            El lado no-inverso se usa para salvar la representaci&#x00f3;n en memoria a la base de datos.
+        </para>
+
+        <para>
+            Puedes definir una asociaci&#x00f3;n bidireccional uno-a-muchos mapeando una asociaci&#x00f3;n uno-a-muchos
+            a la misma columna (o columnas) de tabla como una asociaci&#x00f3;n muchos-a-uno y declarando el
+            extremo multivaluado <literal>inverse="true"</literal>.
+        </para>
+
+        <programlisting><![CDATA[<class name="Parent">
+    <id name="id" column="parent_id"/>
+    ....
+    <set name="children" inverse="true">
+        <key column="parent_id"/>
+        <one-to-many class="Child"/>
+    </set>
+</class>
+
+<class name="eg.Child">
+    <id name="id" column="id"/>
+    ....
+    <many-to-one name="parent" 
+        class="Parent" 
+        column="parent_id"
+        not-null="true"/>
+</class>]]></programlisting>
+
+        <para>
+            Mapear un extremo de una asociaci&#x00f3;n con <literal>inverse="true"</literal> no afecta
+            la operaci&#x00f3;n de cascadas; &#x00e9;stos son conceptos ortogonales!
+        </para>
+
+    </sect2>
+
+    <sect2 id="collections-indexedbidirectional">
+        <title>Asociaciones bidireccionales con colecciones indexadas</title>
+        <para>
+            Requiere especial consideraci&#x00f3;n una asociaci&#x00f3;n bidireccional donde un extremo est&#x00e9; representado
+            como una <literal>&lt;list&gt;</literal> o <literal>&lt;map&gt;</literal>. Si hay una propiedad
+            de la clase hija que mapee a la columna &#x00ed;ndice, no hay problema, podemos seguir usando
+            <literal>inverse="true"</literal> en el mapeo de la colecci&#x00f3;n:
+        </para>
+        
+        <programlisting><![CDATA[<class name="Parent">
+    <id name="id" column="parent_id"/>
+    ....
+    <map name="children" inverse="true">
+        <key column="parent_id"/>
+        <map-key column="name" 
+            type="string"/>
+        <one-to-many class="Child"/>
+    </map>
+</class>
+
+<class name="Child">
+    <id name="id" column="child_id"/>
+    ....
+    <property name="name" 
+        not-null="true"/>
+    <many-to-one name="parent" 
+        class="Parent" 
+        column="parent_id"
+        not-null="true"/>
+</class>]]></programlisting>
+
+        <para>
+            Pero, si no existe tal proiedad en la clase hija, no podemos pensar en la asociaci&#x00f3;n como
+            verdaderamente bidireccional (hay informaci&#x00f3;n en un extremo de la asociaci&#x00f3;n que no est&#x00e1;
+            disponible en el otro extremo). En este caso, no podemos mapear la colecci&#x00f3;n con
+            <literal>inverse="true"</literal>. En cambio, podr&#x00ed;amos usar el siguiente mapeo:
+        </para>
+
+        <programlisting><![CDATA[<class name="Parent">
+    <id name="id" column="parent_id"/>
+    ....
+    <map name="children">
+        <key column="parent_id"
+            not-null="true"/>
+        <map-key column="name" 
+            type="string"/>
+        <one-to-many class="Child"/>
+    </map>
+</class>
+
+<class name="Child">
+    <id name="id" column="child_id"/>
+    ....
+    <many-to-one name="parent" 
+        class="Parent" 
+        column="parent_id"
+        insert="false"
+        update="false"
+        not-null="true"/>
+</class>]]></programlisting>
+
+       <para>
+           Nota que, en este mapeo, el extremo de la asociaci&#x00f3;n valuado en colecci&#x00f3;n es responsable de las
+           actualizaciones a la clave for&#x00e1;nea.
+       </para>
+
+    </sect2>
+
+    <sect2 id="collections-ternary">
+        <title>Asociaciones ternarias</title>
+
+        <para>
+            Hay tres enfoques posibles para mapear una asociaci&#x00f3;n ternaria.
+            Una es usar un <literal>Map</literal> con una asociaci&#x00f3;n como su &#x00ed;ndice:
+        </para>
+
+        <programlisting><![CDATA[<map name="contracts">
+    <key column="employer_id" not-null="true"/>
+    <map-key-many-to-many column="employee_id" class="Employee"/>
+    <one-to-many class="Contract"/>
+</map>]]></programlisting>
+            
+            <programlisting><![CDATA[<map name="connections">
+    <key column="incoming_node_id"/>
+    <map-key-many-to-many column="outgoing_node_id" class="Node"/>
+    <many-to-many column="connection_id" class="Connection"/>
+</map>]]></programlisting>
+            
+        <para>
+            Un segundo enfoque es simplemente remodelar la asociaci&#x00f3;n como una clase de entidad.
+            Este es el enfoque que usamos m&#x00e1;s comunmente.
+        </para>
+        
+        <para>
+            Una alternativa final es usar elementos compuestos, que discutiremos m&#x00e1;s adelante.
+        </para>
+        
+    </sect2>
+    
+    <sect2 id="collections-idbag" revision="1">
+        <title><literal>Usando un &lt;idbag&gt;</literal></title>
+
+        <para>
+            Si has adoptado completamente nuestra visi&#x00f3;n de que las claves compuestas son una
+            cosa mala y que las entidades deben tener identificadores sit&#x00e9;ticos (claves delegadas),
+            entonces podr&#x00ed;as encontrar un poco raro que todas las asociaciones muchos a muchos y
+            las colecciones de valores que hemos mostrado hasta ahora mapeen a tablas con claves
+            compuestas! Ahora, este punto es discutible; una tabla de pura asociaci&#x00f3;n no parece
+            beneficiarse demasiado de una clave delegada (aunque s&#x00ed; <emphasis>podr&#x00ed;a</emphasis> una
+            colecci&#x00f3;n de valores compuestos). Sin embargo, Hibernate provee una funcionalidad que
+            te permite mapear asociaciones muchos a muchos y colecciones de valores a una tabla con
+            una clave delegada.
+        </para>
+
+        <para>
+            El elemento <literal>&lt;idbag&gt;</literal> te permite mapear una <literal>List</literal>
+            (o <literal>Collection</literal>) con sem&#x00e1;ntica de bag.
+        </para>
+
+<programlisting><![CDATA[<idbag name="lovers" table="LOVERS">
+    <collection-id column="ID" type="long">
+        <generator class="sequence"/>
+    </collection-id>
+    <key column="PERSON1"/>
+    <many-to-many column="PERSON2" class="Person" fetch="join"/>
+</idbag>]]></programlisting>
+
+        <para>
+            Como puedes ver, un <literal>&lt;idbag&gt;</literal> tiene un generador de id sint&#x00e9;tico,
+            igual que una clase de entidad! Una clave delegada diferente se asigna a cada fila
+            de la colecci&#x00f3;n. Hibernate no provee ning&#x00fa;n mecanismo para descubrir el valor de clave
+            delegada de una fila en particular, sin embargo.
+        </para>
+
+        <para>
+            Observa que el rendimiento de actualizaci&#x00f3;n de un <literal>&lt;idbag&gt;</literal> es
+            <emphasis>mucho</emphasis> mejor que el de un <literal>&lt;bag&gt;</literal> regular!
+            Hibernate puede localizar filas individuales eficientemente y actualizarlas o borrarlas
+            individualmente, igual que si fuese una lista, mapa o conjunto.
+        </para>
+
+        <para>
+            En la implementaci&#x00f3;n actual, la estrategia de generaci&#x00f3;n de identificador
+            <literal>native</literal> no est&#x00e1; soportada para identificadores de colecciones
+            <literal>&lt;idbag&gt;</literal>.
+        </para>
+
+    </sect2>
+
+    </sect1>
+    
+    <!--undocumenting this stuff -->
+    
+    <!--sect1 id="collections-heterogeneous">
+        <title>Heterogeneous Associations</title>
+
+        <para>
+            The <literal>&lt;many-to-any&gt;</literal> and <literal>&lt;index-many-to-any&gt;</literal>
+            elements provide for true heterogeneous associations. These mapping elements work in the
+            same way as the <literal>&lt;any&gt;</literal> element - and should also be used
+            rarely, if ever.
+        </para>
+
+    </sect1-->
+
+    <sect1 id="collections-example" revision="1">
+        <title>Ejemplos de colecci&#x00f3;n</title>
+
+        <para>
+            Las secciones previas son bastantes confusas. As&#x00ed; que miremos un ejemplo.
+            Esta clase:
+        </para>
+
+        <programlisting><![CDATA[package eg;
+import java.util.Set;
+
+public class Parent {
+    private long id;
+    private Set children;
+
+    public long getId() { return id; }
+    private void setId(long id) { this.id=id; }
+
+    private Set getChildren() { return children; }
+    private void setChildren(Set children) { this.children=children; }
+
+    ....
+    ....
+}]]></programlisting>
+
+        <para>
+            tiene una colecci&#x00f3;n de instancias de <literal>Child</literal>.
+            Si cada hijo tiene como mucho un padre, el mapeo m&#x00e1;s natural es
+            una asociaci&#x00f3;n uno-a-muchos:
+        </para>
+
+        <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="Parent">
+        <id name="id">
+            <generator class="sequence"/>
+        </id>
+        <set name="children">
+            <key column="parent_id"/>
+            <one-to-many class="Child"/>
+        </set>
+    </class>
+
+    <class name="Child">
+        <id name="id">
+            <generator class="sequence"/>
+        </id>
+        <property name="name"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+        <para>
+            Esto mapea a las siguientes definiciones de tablas:
+        </para>
+
+        <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255), parent_id bigint )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+        <para>
+            Si el padre es <emphasis>requerido</emphasis>, usa una asociaci&#x00f3;n bidireccional
+            uno-a-muchos:
+        </para>
+
+        <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="Parent">
+        <id name="id">
+            <generator class="sequence"/>
+        </id>
+        <set name="children" inverse="true">
+            <key column="parent_id"/>
+            <one-to-many class="Child"/>
+        </set>
+    </class>
+
+    <class name="Child">
+        <id name="id">
+            <generator class="sequence"/>
+        </id>
+        <property name="name"/>
+        <many-to-one name="parent" class="Parent" column="parent_id" not-null="true"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+        <para>
+            Observa la restricci&#x00f3;n <literal>NOT NULL</literal>:
+        </para>
+
+        <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null
+                     primary key,
+                     name varchar(255),
+                     parent_id bigint not null )
+alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+
+        <para>
+            Alternativamente, si absolutamente insistes que esta asociaci&#x00f3;n debe ser unidireccional,
+            puedes declarar la restricci&#x00f3;n <literal>NOT NULL</literal> en el mapeo de
+            <literal>&lt;key&gt;</literal>:
+        </para>
+
+        <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="Parent">
+        <id name="id">
+            <generator class="sequence"/>
+        </id>
+        <set name="children">
+            <key column="parent_id" not-null="true"/>
+            <one-to-many class="Child"/>
+        </set>
+    </class>
+
+    <class name="Child">
+        <id name="id">
+            <generator class="sequence"/>
+        </id>
+        <property name="name"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+        <para>
+            En la otra mano, si un hijo pudiera tener m&#x00fa;ltiples padres, ser&#x00ed;a apropiada
+            una asociaci&#x00f3;n muchos-a-muchos:
+        </para>
+
+        <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="Parent">
+        <id name="id">
+            <generator class="sequence"/>
+        </id>
+        <set name="children" table="childset">
+            <key column="parent_id"/>
+            <many-to-many class="Child" column="child_id"/>
+        </set>
+    </class>
+
+    <class name="Child">
+        <id name="id">
+            <generator class="sequence"/>
+        </id>
+        <property name="name"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+        <para>
+            Definiciones de tabla:
+        </para>
+
+        <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+create table child ( id bigint not null primary key, name varchar(255) )
+create table childset ( parent_id bigint not null,
+                        child_id bigint not null,
+                        primary key ( parent_id, child_id ) )
+alter table childset add constraint childsetfk0 (parent_id) references parent
+alter table childset add constraint childsetfk1 (child_id) references child]]></programlisting>
+
+        <para>
+            Para m&#x00e1;s ejemplos y un paseo completo a trav&#x00e9;s del mapeo de relaciones padre/hijo,
+            ver <xref linkend="example-parentchild"/>.
+        </para>
+        
+        <para>
+            Son posibles mapeos de asociaci&#x00f3;n a&#x00fa;n m&#x00e1;s complejos. Catalogaremos todas las posibilidades
+            en el pr&#x00f3;ximo cap&#x00ed;tulo.
+        </para>
+
+    </sect1>
+
+</chapter>

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/component_mapping.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/component_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/component_mapping.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/component_mapping.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,403 @@
+<chapter id="components">
+    <title>Mapeo de Componentes</title>
+
+    <para>
+        La noci&#x00f3;n de un <emphasis>componente</emphasis> es reusada en muchos contextos diferentes,
+        para prop&#x00f3;sitos diferentes, a trav&#x00e9;s de Hibernate.
+    </para>
+
+    <sect1 id="components-dependentobjects">
+        <title>Objetos dependientes</title>
+
+        <para>
+            Un componente es un objeto contenido que es persistido como un tipo de valor, no una
+            referencia de entidad. El t&#x00e9;rmino "componente" hace referencia a la noci&#x00f3;n orientada a
+            objetos de composici&#x00f3;n (no a componentes a nivel de arquitectura). Por ejemplo, podr&#x00ed;as
+            modelar una persona como:
+        </para>
+
+        <programlisting><![CDATA[public class Person {
+    private java.util.Date birthday;
+    private Name name;
+    private String key;
+    public String getKey() {
+        return key;
+    }
+    private void setKey(String key) {
+        this.key=key;
+    }
+    public java.util.Date getBirthday() {
+        return birthday;
+    }
+    public void setBirthday(java.util.Date birthday) {
+        this.birthday = birthday;
+    }
+    public Name getName() {
+        return name;
+    }
+    public void setName(Name name) {
+        this.name = name;
+    }
+    ......
+    ......
+}]]></programlisting>
+
+<programlisting><![CDATA[public class Name {
+    char initial;
+    String first;
+    String last;
+    public String getFirst() {
+        return first;
+    }
+    void setFirst(String first) {
+        this.first = first;
+    }
+    public String getLast() {
+        return last;
+    }
+    void setLast(String last) {
+        this.last = last;
+    }
+    public char getInitial() {
+        return initial;
+    }
+    void setInitial(char initial) {
+        this.initial = initial;
+    }
+}]]></programlisting>
+
+        <para>
+            Ahora <literal>Name</literal> puede ser persistido como un componente de
+            <literal>Person</literal>. Observa que <literal>Name</literal> define m&#x00e9;todos
+            getter y setter para sus propiedades persistentes, pero no necesita declarar
+            ninguna interface ni propiedades identificadoras.
+        </para>
+
+        <para>
+            Nuestro mapeo de Hibernate se ver&#x00ed;a as&#x00ed;:
+        </para>
+
+        <programlisting><![CDATA[<class name="eg.Person" table="person">
+    <id name="Key" column="pid" type="string">
+        <generator class="uuid.hex"/>
+    </id>
+    <property name="birthday" type="date"/>
+    <component name="Name" class="eg.Name"> <!-- class attribute optional -->
+        <property name="initial"/>
+        <property name="first"/>
+        <property name="last"/>
+    </component>
+</class>]]></programlisting>
+
+        <para>
+            La tabla person tendr&#x00ed;a las columnas <literal>pid</literal>,
+            <literal>birthday</literal>,
+            <literal>initial</literal>,
+            <literal>first</literal> y
+            <literal>last</literal>.
+        </para>
+
+        <para>
+            Como todos los tipos de valor, los componentes no soportan referencias compartidas.
+            En otras palabras, dos personas pueden tener el mismo nombre, pero los dos objetos
+            persona contendr&#x00ed;an dos objetos nombre independientes, s&#x00f3;lo "iguales" en valor.
+            La sem&#x00e1;ntica de valor nulo de un componente es <emphasis>ad hoc</emphasis>.
+            Cuando se recargue el objeto contenedor, Hibernate asumir&#x00e1; que si todas las columnas del
+            componente son nulas, el componente entero es nulo. Esto debe estar bien para la mayor&#x00ed;a
+            de prop&#x00f3;sitos.
+        </para>
+
+        <para>
+            Las propiedades de un componentes pueden ser de cualquier tipo de Hibernate
+            (colecciones, muchos-a-uno, asociaciones, otros componentes, etc). Los componentes
+            anidados <emphasis>no</emphasis> deben ser considerados un uso ex&#x00f3;tico. Hibernate est&#x00e1;
+            concebido para soportar un modelo de objetos granularizado en fino.
+        </para>
+
+        <para>
+            El elemento <literal>&lt;component&gt;</literal> permite un subelemento
+            <literal>&lt;parent&gt;</literal> que mapee una propiedad de la clase del componente
+            como una referencia de regreso a la entidad contenedora.
+        </para>
+
+        <programlisting><![CDATA[<class name="eg.Person" table="person">
+    <id name="Key" column="pid" type="string">
+        <generator class="uuid.hex"/>
+    </id>
+    <property name="birthday" type="date"/>
+    <component name="Name" class="eg.Name" unique="true">
+        <parent name="namedPerson"/> <!-- reference back to the Person -->
+        <property name="initial"/>
+        <property name="first"/>
+        <property name="last"/>
+    </component>
+</class>]]></programlisting>
+
+    </sect1>
+
+    <sect1 id="components-incollections" revision="1">
+        <title>Colecciones de objetos dependientes</title>
+
+        <para>
+            Las colecciones de componentes est&#x00e1;n soportadas (por ejemplo,
+            un array de tipo <literal>Name</literal>). Declara tu colecci&#x00f3;n
+            de componentes remplazando la etiqueta <literal>&lt;element&gt;</literal>
+            por una etiqueta <literal>&lt;composite-element&gt;</literal>.
+        </para>
+
+        <programlisting><![CDATA[<set name="someNames" table="some_names" lazy="true">
+    <key column="id"/>
+    <composite-element class="eg.Name"> <!-- class attribute required -->
+        <property name="initial"/>
+        <property name="first"/>
+        <property name="last"/>
+    </composite-element>
+</set>]]></programlisting>
+
+        <para>
+            Nota: si defines un <literal>Set</literal> de elementos compuestos, es muy
+            importante implementar <literal>equals()</literal> y <literal>hashCode()</literal>
+            correctamente.
+        </para>
+
+        <para>
+            Los elementos compuestos pueden contener componentes pero no colecciones.
+            Si tu elemento compuesto contiene a su vez componentes, usa la etiqueta
+            <literal>&lt;nested-composite-element&gt;</literal>. Este es un caso bastante
+            ex&#x00f3;tico - una colecci&#x00f3;n de componentes que a su vez tienen componentes. A esta
+            altura debes estar pregunt&#x00e1;ndote si una asociaci&#x00f3;n uno-a-muchos es m&#x00e1;s
+            apropiada. Intenta remodelar el elemento compuesto como una entidad - pero
+            observa que aunque el modelo Java es el mismo, el modelo relacional y la
+            sem&#x00e1;ntica de persistencia siguen siendo ligeramente diferentes.
+        </para>
+
+        <para>
+            Por favor observa que un mapeo de elemento compuesto no soporta
+            propiedades nulables si est&#x00e1;s usando un <literal>&lt;set&gt;</literal>.
+            Hibernate tiene que usar cada columna para identificar un registro
+            al borrar objetos (no hay una columna clave primaria separada en la tabla del
+            elemento compuesto), lo que es imposible con valores nulos. Tienes que, o bien usar
+            s&#x00f3;lo propiedades no nulas en un elemento compuesto o elegir un
+            <literal>&lt;list&gt;</literal>, <literal>&lt;map&gt;</literal>,
+            <literal>&lt;bag&gt;</literal> o <literal>&lt;idbag&gt;</literal>.
+        </para>
+
+        <para>
+            Un caso especial de un elemento compuesto es un elemento compuesto con un
+            elemento anidado <literal>&lt;many-to-one&gt;</literal>. Un mapeo como este
+            te permite mapear columnas extra de una tabla de asociaci&#x00f3;n muchos-a-muchos
+            a la clase del elemento compuesto. La siguiente es una asociaci&#x00f3;n muchos-a-muchos
+            de <literal>Order</literal> a <literal>Item</literal> donde
+            <literal>purchaseDate</literal>, <literal>price</literal> y
+            <literal>quantity</literal> son propiedades de la asociaci&#x00f3;n:
+        </para>
+
+        <programlisting><![CDATA[<class name="eg.Order" .... >
+    ....
+    <set name="purchasedItems" table="purchase_items" lazy="true">
+        <key column="order_id">
+        <composite-element class="eg.Purchase">
+            <property name="purchaseDate"/>
+            <property name="price"/>
+            <property name="quantity"/>
+            <many-to-one name="item" class="eg.Item"/> <!-- class attribute is optional -->
+        </composite-element>
+    </set>
+</class>]]></programlisting>
+
+        <para>
+            Por supuesto, no puede haber una referencia a la compra del otro lado para la
+            navegaci&#x00f3;n bidireccional de la asociaci&#x00f3;n. Recuerda que los componentes son tipos de
+            valor no permiten referencias compartidas. Una sola <literal>Purchase</literal> puede
+            estar en el conjunto de una <literal>Order</literal>, pero no puede ser referenciada
+            por el <literal>Item</literal> al mismo tiempo.
+        </para>
+
+        <para>Incluso son posibles las asociaciones ternarias (o cuaternarias, etc):</para>
+
+        <programlisting><![CDATA[<class name="eg.Order" .... >
+    ....
+    <set name="purchasedItems" table="purchase_items" lazy="true">
+        <key column="order_id">
+        <composite-element class="eg.OrderLine">
+            <many-to-one name="purchaseDetails class="eg.Purchase"/>
+            <many-to-one name="item" class="eg.Item"/>
+        </composite-element>
+    </set>
+</class>]]></programlisting>
+
+        <para>
+            Los elementos compuestos pueden aparecer en consultas usando la misma
+            sint&#x00e1;xis que las asociaciones a otras entidades.
+        </para>
+
+    </sect1>
+
+    <sect1 id="components-asmapindex">
+        <title>Componentes como &#x00ed;ndices de Map</title>
+
+        <para>
+            El elemento <literal>&lt;composite-map-key&gt;</literal> te permite mapear
+            una clase componente como la clave de un <literal>Map</literal>. Aseg&#x00fa;rate que
+            sobrescribes <literal>hashCode()</literal> y <literal>equals()</literal>
+            correctamente en la clase componente.
+        </para>
+    </sect1>
+
+    <sect1 id="components-compositeid" revision="1">
+        <title>Componentes como identificadores compuestos</title>
+
+        <para>
+            Puedes usar un componente como un identidicador de una clase entidad. Tu clase
+            componente debe satisfacer ciertos requerimientos:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    Debe implementar <literal>java.io.Serializable</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Debe re-implementar <literal>equals()</literal> y
+                    <literal>hashCode()</literal>, consistentemente con la
+                    noci&#x00f3;n de base de datos de igualdad de clave compuesta.
+                </para>
+            </listitem>
+        </itemizedlist>
+        
+        <para>
+            <emphasis>Nota: en Hibernat3, el segundo requerimiento no es absolutamente un
+            requerimiento r&#x00ed;gido de Hibernate. Pero de todas formas, h&#x00e1;zlo.</emphasis>
+        </para>
+
+        <para>
+            No puedes usar un <literal>IdentifierGenerator</literal> para generar claves
+            compuestas. La aplicaci&#x00f3;n debe, en cambio, asignar sus propios identificadores.
+        </para>
+
+        <para>
+            Usa la etiqueta <literal>&lt;composite-id&gt;</literal> (con elementos
+            anidados <literal>&lt;key-property&gt;</literal>) en lugar de la usual
+            declaraci&#x00f3;n <literal>&lt;id&gt;</literal>. Por ejemplo, la clase
+            <literal>OrderLine</literal> tiene una clave primaria que depende de
+            la clave primaria (compuesta) de <literal>Order</literal>.
+        </para>
+
+        <programlisting><![CDATA[<class name="OrderLine">
+    
+    <composite-id name="id" class="OrderLineId">
+        <key-property name="lineId"/>
+        <key-property name="orderId"/>
+        <key-property name="customerId"/>
+    </composite-id>
+    
+    <property name="name"/>
+    
+    <many-to-one name="order" class="Order"
+            insert="false" update="false">
+        <column name="orderId"/>
+        <column name="customerId"/>
+    </many-to-one>
+    ....
+    
+</class>]]></programlisting>
+
+        <para>
+            Ahora, cualquier clave for&#x00e1;nea que referencie la tabla de <literal>OrderLine</literal>
+            es tambi&#x00e9;n compuesta. Debes declarar esto en tus mapeos de otras clases. Una asociaci&#x00f3;n
+            a <literal>OrderLine</literal> ser&#x00ed;a mapeado as&#x00ed;:
+        </para>
+
+        <programlisting><![CDATA[<many-to-one name="orderLine" class="OrderLine">
+<!-- the "class" attribute is optional, as usual -->
+    <column name="lineId"/>
+    <column name="orderId"/>
+    <column name="customerId"/>
+</many-to-one>]]></programlisting>
+
+        <para>
+            (Nota que la etiqueta <literal>&lt;column&gt;</literal> es una alternativa al
+            atributo <literal>column</literal> en cualquier sitio.)
+        </para>
+        
+        <para>
+            Una asociaci&#x00f3;n <literal>muchos-a-muchos</literal> a <literal>OrderLine</literal>
+            tambi&#x00e9;n usa la clave for&#x00e1;nea compuesta:
+        </para>
+    
+    <programlisting><![CDATA[<set name="undeliveredOrderLines">
+    <key column name="warehouseId"/>
+    <many-to-many class="OrderLine">
+        <column name="lineId"/>
+        <column name="orderId"/>
+        <column name="customerId"/>
+    </many-to-many>
+</set>]]></programlisting>
+
+        <para>
+            La colecci&#x00f3;n de <literal>OrderLine</literal>s en <literal>Order</literal> usar&#x00ed;a:
+        </para>
+
+    <programlisting><![CDATA[<set name="orderLines" inverse="true">
+    <key>
+        <column name="orderId"/>
+        <column name="customerId"/>
+    </key>
+    <one-to-many class="OrderLine"/>
+</set>]]></programlisting>
+
+        <para>
+            (El elemento <literal>&lt;one-to-many&gt;</literal>, como es usual, no declara columnas.)
+        </para>
+        
+        <para>
+            Si <literal>OrderLine</literal> posee una colecci&#x00f3;n por s&#x00ed; misma, tiene tambi&#x00e9;n
+            una clave for&#x00e1;nea compuesta.
+        </para>
+
+        <programlisting><![CDATA[<class name="OrderLine">
+    ....
+    ....
+    <list name="deliveryAttempts">
+        <key>   <!-- a collection inherits the composite key type -->
+            <column name="lineId"/>
+            <column name="orderId"/>
+            <column name="customerId"/>
+        </key>
+        <list-index column="attemptId" base="1"/>
+        <composite-element class="DeliveryAttempt">
+            ...
+        </composite-element>
+    </set>
+</class>]]></programlisting>
+
+    </sect1>
+
+    <sect1 id="components-dynamic" revision="1">
+        <title>Componentes din&#x00e1;micos</title>
+
+        <para>
+            Puedes incluso mapear una propiedad de tipo <literal>Map</literal>:
+        </para>
+
+    <programlisting><![CDATA[<dynamic-component name="userAttributes">
+    <property name="foo" column="FOO" type="string"/>
+    <property name="bar" column="BAR" type="integer"/>
+    <many-to-one name="baz" class="Baz" column="BAZ_ID"/>
+</dynamic-component>]]></programlisting>
+
+        <para>
+            La sem&#x00e1;ntica de un mapeo <literal>&lt;dynamic-component&gt;</literal> es &#x00ed;dentica
+            a la de <literal>&lt;component&gt;</literal>. La ventaja de este tipo de mapeos es
+            la habilidad para determinar las propiedades reales del bean en tiempo de despliegue,
+            s&#x00f3;lo con editar el documento de mapeo. La manipulaci&#x00f3;n del documento de mapeo en tiempo
+            de ejecuci&#x00f3;n es tambi&#x00e9;n posible, usando un analizador DOM. Incluso mejor, puedes acceder
+            (y cambiar) el metamodelo de tiempo de configuraci&#x00f3;n de Hibernate por medio del objeto
+            <literal>Configuration</literal>.
+        </para>
+
+    </sect1>
+
+</chapter>

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/configuration.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/configuration.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/configuration.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/configuration.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,1761 @@
+<chapter id="session-configuration" revision="1">
+
+    <title>Configuraci&#x00f3;n</title>
+    
+    <para>
+        Debido a que Hibernate est&#x00e1; dise&#x00f1;ado para operar en muchos entornos
+        diferentes, hay un gran n&#x00fa;mero de par&#x00e1;metros de configuraci&#x00f3;n.
+        Afortunadamente, la mayor&#x00ed;a tiene valores por defecto sensibles e Hibernate
+        se distribuye con un fichero <literal>hibernate.properties</literal> de ejemplo en 
+        <literal>etc/</literal> que muestra las diversas opciones. Tan s&#x00f3;lo pon el
+        fichero de ejemplo en tu classpath y personal&#x00ed;zalo.
+    </para>
+
+    <sect1 id="configuration-programmatic" revision="1">
+        <title>Configuraci&#x00f3;n program&#x00e1;tica</title>
+
+        <para>
+            Una instancia de <literal>org.hibernate.cfg.Configuration</literal>
+            representa un conjunto entero de mapeos de los tipos Java de una aplicaci&#x00f3;n
+            a una base de datos SQL. La <literal>Configuration</literal> es usada para
+            construir una <literal>SessionFactory</literal> (inmutable). Los mapeos se
+            compilan de varios ficheros de mapeo XML.
+        </para>
+
+        <para>
+            Puedes obtener una instancia de <literal>Configuration</literal> instanci&#x00e1;ndola
+            directamente y especificando documentos de mapeo XML. Si los ficheros de mapeo
+            est&#x00e1;n en el classpath, usa <literal>addResource()</literal>:
+        </para>
+
+        <programlisting><![CDATA[Configuration cfg = new Configuration()
+    .addResource("Item.hbm.xml")
+    .addResource("Bid.hbm.xml");]]></programlisting>
+
+        <para>
+            Una forma alternativa (a veces mejor) es especificar la clase mapeada,
+            y dejar que Hibernate encuentre el documento de mapeo por ti:
+        </para>
+
+        <programlisting><![CDATA[Configuration cfg = new Configuration()
+    .addClass(org.hibernate.auction.Item.class)
+    .addClass(org.hibernate.auction.Bid.class);]]></programlisting>
+
+        <para>
+            Entonces Hibernate buscar&#x00e1; ficheros de mapeo llamados
+            <literal>/org/hibernate/auction/Item.hbm.xml</literal> y
+            <literal>/org/hibernate/auction/Bid.hbm.xml</literal> en el classpath.
+            Este enfoque elimina cualquier nombre de fichero en el c&#x00f3;digo.
+        </para>
+        
+        <para>
+            Una <literal>Configuration</literal> tambi&#x00e9;n te permite especificar
+            propiedades de configuraci&#x00f3;n:
+        </para>
+
+        <programlisting><![CDATA[Configuration cfg = new Configuration()
+    .addClass(org.hibernate.auction.Item.class)
+    .addClass(org.hibernate.auction.Bid.class)
+    .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
+    .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
+    .setProperty("hibernate.order_updates", "true");]]></programlisting>
+    
+        <para>
+            Esta no es la &#x00fa;nica forma de pasar propiedades de configuraci&#x00f3;n
+            a Hibernate. La diversas opciones incluyen:
+        </para>
+
+        <orderedlist spacing="compact">
+            <listitem>
+                <para>
+                    Pasar una instancia de <literal>java.util.Properties</literal> a
+                    <literal>Configuration.setProperties()</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Colocar <literal>hibernate.properties</literal> en un directorio
+                    ra&#x00ed;z del classpath.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Establecer propiedades <literal>System</literal>
+                    usando <literal>java -Dproperty=value</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Incluir elementos <literal>&lt;property&gt;</literal>
+                    en <literal>hibernate.cfg.xml</literal> (discutido luego).
+                </para>
+            </listitem>
+        </orderedlist>
+
+        <para>
+            <literal>hibernate.properties</literal> es el enfoque m&#x00e1;s f&#x00e1;cil
+            si quieres comenzar r&#x00e1;pido.
+        </para>
+
+        <para>
+            La <literal>Configuration</literal> est&#x00e1; concebida como un objeto
+            de tiempo de arranque, para ser descartado una vez que una
+            <literal>SessionFactory</literal> es creada.
+        </para>
+
+    </sect1>
+    
+    <sect1 id="configuration-sessionfactory">
+        <title>Obteniendo una SessionFactory</title>
+
+        <para>
+            Cuando todos los mapeos han sido parseados por la <literal>Configuration</literal>, 
+            la aplicaci&#x00f3;n debe obtener una f&#x00e1;brica de instancias de <literal>Session</literal>.
+            Esta f&#x00e1;brica est&#x00e1; concebida para ser compartida por todas las hebras de
+            aplicaci&#x00f3;n:
+        </para>
+
+        <programlisting><![CDATA[SessionFactory sessions = cfg.buildSessionFactory();]]></programlisting>
+
+        <para>
+            Hibernate permite que tu aplicaci&#x00f3;n instancie m&#x00e1;s de una
+            <literal>SessionFactory</literal>. Esto es &#x00fa;til si est&#x00e1;s usando
+            m&#x00e1;s de una base de datos.
+        </para>
+
+    </sect1>
+
+    <sect1 id="configuration-hibernatejdbc" revision="1">
+        <title>Conexiones JDBC</title>
+
+        <para>
+            Usualmente, quieres que la <literal>SessionFactory</literal> cree y almacene
+            en pool conexiones JDBC para ti. Si adoptas este enfoque, abrir una <literal>Session</literal> 
+            es tan simple como:
+        </para>
+
+        <programlisting><![CDATA[Session session = sessions.openSession(); // open a new Session]]></programlisting>
+        
+        <para>
+            En cuanto hagas algo que requiera acceso a la base de datos, se obtendr&#x00e1; una
+            conexi&#x00f3;n JDBC del pool.
+        </para>
+
+        <para>
+            Para que esto funcione, necesitamos pasar algunas propiedades de conexi&#x00f3;n
+            JDBC a Hibernate. Todos los nombres de propiedades y su sem&#x00e1;ntica
+            est&#x00e1;n definidas en la clase <literal>org.hibernate.cfg.Environment</literal>.
+            Describiremos ahora las configuraciones m&#x00e1;s importantes para la conexi&#x00f3;n
+            JDBC.
+        </para>
+
+        <para>
+            Hibernate obtendr&#x00e1; (y tendr&#x00e1; en pool) conexiones usando
+            <literal>java.sql.DriverManager</literal> si configuras las siguientes propiedades:
+        </para>
+
+        <table frame="topbot">
+            <title>Propiedades JDBC de Hibernate</title>
+            <tgroup cols="2">
+                <colspec colname="c1" colwidth="1*"/>
+                <colspec colname="c2" colwidth="1*"/>
+                <thead>
+                    <row>
+                        <entry>Nombre de propiedad</entry>
+                        <entry>Prop&#x00f3;sito</entry>
+                    </row>
+                </thead>
+            <tbody>
+            <row>
+                <entry>
+                    <literal>hibernate.connection.driver_class</literal>
+                </entry>
+                <entry>
+                    <emphasis>clase del driver jdbc</emphasis>
+                </entry>
+            </row>
+            <row>
+                <entry>
+                    <literal>hibernate.connection.url</literal>
+                </entry>
+                <entry>
+                    <emphasis>URL de jdbc</emphasis>
+                </entry>
+            </row>
+            <row>
+                <entry>
+                    <literal>hibernate.connection.username</literal>
+                </entry>
+                <entry>
+                    <emphasis>usuario de base de datos</emphasis>
+                </entry>
+            </row>
+            <row>
+                <entry>
+                    <literal>hibernate.connection.password</literal>
+                </entry>
+                <entry>
+                    <emphasis>contrase&#x00f1;a del usuario de base de datos</emphasis>
+                </entry>
+            </row>
+            <row>
+                <entry>
+                    <literal>hibernate.connection.pool_size</literal>
+                </entry>
+                <entry>
+                    <emphasis>n&#x00fa;mero m&#x00e1;ximo de conexiones manejadas por pooling</emphasis>
+                </entry>
+            </row>
+            </tbody>
+            </tgroup>
+        </table>
+
+        <para>
+            El algoritmo de pooling de conexiones propio de Hibernate es sin embargo
+            algo rudimentario. Est&#x00e1; concebido para ayudarte a comenzar y 
+            <emphasis>no est&#x00e1; concebido para usar en un sistema de producci&#x00f3;n</emphasis>
+            ni siquiera para pruebas de rendimiento. Debes usar un pool de terceros para
+            un mejor rendimiento y estabilidad. S&#x00f3;lo remplaza la propiedad
+            <literal>hibernate.connection.pool_size</literal> con configuraciones
+            espec&#x00ed;ficas del pool de conexiones. Esto desactivar&#x00e1; el pool
+            interno de Hibernate. Por ejemplo, podr&#x00ed;as querer usar C3P0.
+        </para>
+
+        <para>
+            C3P0 es un pool de conexiones JDBC de c&#x00f3;digo abierto distribuido
+            junto a Hibernate en el directorio <literal>lib</literal>.
+            Hibernate usar&#x00e1; su <literal>C3P0ConnectionProvider</literal>
+            para pooling de conexiones si estableces propiedades <literal>hibernate.c3p0.*</literal>.
+            Si quieres usar Proxool refi&#x00e9;rete al <literal>hibernate.properties</literal>
+            empaquetado y al sitio web de Hibernate para m&#x00e1;s informaci&#x00f3;n.
+        </para>
+
+        <para>
+            Aqu&#x00ed; hay un fichero <literal>hibernate.properties</literal> de ejemplo para C3P0:
+        </para>
+
+        <programlisting id="c3p0-configuration" revision="1"><![CDATA[hibernate.connection.driver_class = org.postgresql.Driver
+hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
+hibernate.connection.username = myuser
+hibernate.connection.password = secret
+hibernate.c3p0.min_size=5
+hibernate.c3p0.max_size=20
+hibernate.c3p0.timeout=1800
+hibernate.c3p0.max_statements=50
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+        <para>
+            Para su uso en un servidor de aplicaciones, casi siempre debes configurar
+            Hibernate para que obtenga conexiones de un <literal>Datasource</literal>
+            del servidor de aplicaciones registrado en JNDI. Necesitar&#x00e1;s establecer
+            al menos una de las siguientes propiedades:
+        </para>
+
+        <table frame="topbot">
+            <title>Propiedades de Datasource de Hibernate</title>
+            <tgroup cols="2">
+                <colspec colname="c1" colwidth="1*"/>
+                <colspec colname="c2" colwidth="1*"/>
+                <thead>
+                    <row>
+                        <entry>Nombre de propiedad</entry>
+                        <entry>Prop&#x00f3;sito</entry>
+                    </row>
+                </thead>
+            <tbody>
+            <row>
+                <entry>
+                    <literal>hibernate.connection.datasource</literal>
+                </entry>
+                <entry>
+                    <emphasis>nombre del datasource JNDI</emphasis>
+                </entry>
+            </row>
+            <row>
+                <entry>
+                    <literal>hibernate.jndi.url</literal>
+                </entry>
+                <entry>
+                    <emphasis>URL del provedor JNDI</emphasis> (optional)
+                </entry>
+            </row>
+            <row>
+                <entry>
+                    <literal>hibernate.jndi.class</literal>
+                </entry>
+                <entry>
+                    <emphasis>clase de la <literal>InitialContextFactory</literal> de JNDI</emphasis> (opcional)
+                </entry>
+            </row>
+            <row>
+                <entry>
+                    <literal>hibernate.connection.username</literal>
+                </entry>
+                <entry>
+                    <emphasis>usuario de base de datos</emphasis> (opcional)
+                </entry>
+            </row>
+            <row>
+                <entry>
+                    <literal>hibernate.connection.password</literal>
+                </entry>
+                <entry>
+                    <emphasis>contrase&#x00f1;a del usuario de base de datos</emphasis> (opcional)
+                </entry>
+            </row>
+            </tbody>
+            </tgroup>
+        </table>
+
+        <para>
+            He aqu&#x00ed; un fichero <literal>hibernate.properties</literal> de ejemplo
+            para un un datasource JNDI provisto por un servidor de aplicaciones.
+        </para>
+
+        <programlisting><![CDATA[hibernate.connection.datasource = java:/comp/env/jdbc/test
+hibernate.transaction.factory_class = \
+    org.hibernate.transaction.JTATransactionFactory
+hibernate.transaction.manager_lookup_class = \
+    org.hibernate.transaction.JBossTransactionManagerLookup
+hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect]]></programlisting>
+
+        <para>
+            Las conexiones JDBC obtenidas de un datasource JNDI participar&#x00e1;n autom&#x00e1;ticamente
+            en las transacciones del servidor de aplicaciones manejadas por contenedor.
+        </para>
+
+        <para>
+            Pueden darse propiedades de conexi&#x00f3;n arbitrarias anteponiendo
+            "<literal>hibernate.connnection</literal>" al nombre de propiedad.
+            Por ejemplo, puedes especificar un <literal>charSet</literal> usando
+            <literal>hibernate.connection.charSet</literal>.
+        </para>
+
+        <para>
+            Puedes definir tu propia estrategia de plugin para obtener conexiones JDBC implementando
+            la interface <literal>org.hibernate.connection.ConnectionProvider</literal>. Puedes
+            seleccionar una implementaci&#x00f3;n personalizada estableciendo
+            <literal>hibernate.connection.provider_class</literal>.
+        </para>
+
+    </sect1>
+
+    <sect1 id="configuration-optional" revision="1">
+        <title>Par&#x00e1;metros de configuraci&#x00f3;n opcionales</title>
+        
+        <para>
+            Hay un n&#x00fa;mero de otras propiedades que controlan el comportamiento
+            de Hibernate en tiempo de ejecuci&#x00f3;n. Todas son opcionales y tienen
+            valores por defecto razonables.
+        </para>
+
+        <para>
+            <emphasis>Advertencia: algunas de estas propiedades son de "nivel-de-sistema"
+            solamente.</emphasis>. Las propiedades a nivel de sistema s&#x00f3;lo pueden ser
+            establecidas por medio de <literal>java -Dproperty=value</literal> o
+            <literal>hibernate.properties</literal>. <emphasis>No</emphasis> pueden
+            establecerse por medio de las otras t&#x00e9;cnicas arriba descritas.
+        </para>
+
+        <table frame="topbot" id="configuration-optional-properties" revision="8">
+            <title>Propiedades de Configuraci&#x00f3;n de Hibernate</title>
+            <tgroup cols="2">
+                <colspec colname="c1" colwidth="1*"/>
+                <colspec colname="c2" colwidth="1*"/>
+                <thead>
+                    <row>
+                        <entry>Nombre de propiedad</entry>
+                        <entry>Prop&#x00f3;sito</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>
+                            <literal>hibernate.dialect</literal>
+                        </entry>
+                        <entry>
+                            El nombre de clase de un <literal>Dialect</literal>
+                            de Hibernate que permite a Hibernate generar SQL optimizado
+                            para una base de datos relacional en particular.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>full.classname.of.Dialect</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.show_sql</literal>
+                        </entry>
+                        <entry>
+                            Escribe todas las sentencias SQL a la consola.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.default_schema</literal>
+                        </entry>
+                        <entry>
+                            Cualifica, en el SQL generado, los nombres de tabla sin cualificar
+                            con el esquema/tablespace dado.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>SCHEMA_NAME</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.default_catalog</literal>
+                        </entry>
+                        <entry>
+                            Cualifica, en el SQL generado, los nombres de tabla sin cualificar
+                            con el cat&#x00e1;logo dado.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>CATALOG_NAME</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.session_factory_name</literal>
+                        </entry>
+                        <entry>
+                            La <literal>SessionFactory</literal> ser&#x00e1;
+                            ligada a este nombre en JNDI autom&#x00e1;ticamente
+                            despu&#x00e9;s de ser creada.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>jndi/composite/name</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.max_fetch_depth</literal>
+                        </entry>
+                        <entry>
+                            Establece una "profundidad" m&#x00e1;xima del
+                            &#x00e1;rbol de recuperaci&#x00f3;n por outer join
+                            para asociaciones de un extremo solo (uno-a-uno, muchos-a-uno).
+                            Un <literal>0</literal> deshabilita la recuperaci&#x00f3;n
+                            por outer join por defecto.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                valores recomendados entre <literal>0</literal> y
+                                <literal>3</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.default_batch_fetch_size</literal>
+                        </entry>
+                        <entry>
+                            Establece un tama&#x00f1;o por defecto para la recuperaci&#x00f3;n
+                            en lote de asociaciones de Hibernate.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                valores recomendados <literal>4</literal>, <literal>8</literal>, 
+                                <literal>16</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.default_entity_mode</literal>
+                        </entry>
+                        <entry>
+                            Establece un modo por defecto de representaci&#x00f3;n de
+                            entidades para todas las sesiones abiertas por esta
+                            <literal>SessionFactory</literal>
+                            <para>
+                                <literal>dynamic-map</literal>, <literal>dom4j</literal>,
+                                <literal>pojo</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.order_updates</literal>
+                        </entry>
+                        <entry>
+                            Fuerza a Hibernate a ordenar las actualizaciones SQL
+                            por el valor de la clave primaria de los items a actualizar.
+                            Esto resultar&#x00e1; en menos bloqueos muertos de transacci&#x00f3;n
+                            en sistemas altamente concurrentes.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.generate_statistics</literal>
+                        </entry>
+                        <entry>
+                            De habilitarse, Hibernate colectar&#x00e1; estad&#x00ed;sticas
+                            &#x00fa;tiles para la afinaci&#x00f3;n de rendimiento.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.use_identifer_rollback</literal>
+                        </entry>
+                        <entry>
+                            De habilitarse, las propiedades identificadoras
+                            generadas ser&#x00e1;n reseteadas a valores por
+                            defecto cuando los objetos sean borrados.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.use_sql_comments</literal>
+                        </entry>
+                        <entry>
+                            De activarse, Hibernate generar&#x00e1; comentarios dentro del SQL,
+                            para una m&#x00e1;s f&#x00e1;cil depuraci&#x00f3;n, por defecto a
+                            <literal>false</literal>.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <table frame="topbot" id="configuration-jdbc-properties" revision="8">
+            <title>Propiedades de JDBC y Conexiones de Hibernate</title>
+            <tgroup cols="2">
+                <colspec colname="c1" colwidth="1*"/>
+                <colspec colname="c2" colwidth="1*"/>
+                <thead>
+                    <row>
+                        <entry>Nombre de propiedad</entry>
+                        <entry>Propo&#x00f3;sito</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>
+                            <literal>hibernate.jdbc.fetch_size</literal>
+                        </entry>
+                        <entry>
+                            Un valor distinto de cero que determina el tama&#x00f1;o
+                            de recuperaci&#x00f3;n de JDBC (llama a
+                            <literal>Statement.setFetchSize()</literal>).
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.jdbc.batch_size</literal>
+                        </entry>
+                        <entry>
+                            Un valor distinto de cero habilita el uso de actualizaciones
+                            en lote de JDBC2 por Hibernate.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                valores recomendados entre <literal>5</literal> y <literal>30</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.jdbc.batch_versioned_data</literal>
+                        </entry>
+                        <entry>
+                            Establece esta propiedad a <literal>true</literal> si tu driver JDBC
+                            devuelve cuentas correctas de filas desde <literal>executeBatch()</literal>
+                            (usualmente es seguro activar esta opci&#x00f3;n). Hibernate usar&#x00e1;
+                            DML en lote para versionar autom&#x00e1;ticamente los datos.
+                            Por defecto a <literal>false</literal>.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.jdbc.factory_class</literal>
+                        </entry>
+                        <entry>
+                            Selecciona un <literal>Batcher</literal> personalizado.
+                            La mayor&#x00ed;a de las aplicaciones no necesitar&#x00e1;n
+                            esta propiedad de configuraci&#x00f3;n.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>classname.of.BatcherFactory</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.jdbc.use_scrollable_resultset</literal>
+                        </entry>
+                        <entry>
+                            Habilita el uso de resultados scrollables de JDBC2 por Hibernate.
+                            Esta propiedad s&#x00f3;lo es necesaria cuando se usan conexiones
+                            JDBC provistas por el usuario, en caso contrario Hibernate usa los
+                            metadatos de conexi&#x00f3;n.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.jdbc.use_streams_for_binary</literal>
+                        </entry>
+                        <entry>
+                            Usa flujos (streams) al escribir/leer tipos
+                            <literal>binary</literal> o <literal>serializable</literal>
+                            a/desde JDBC (propiedad a nivel de sistema).
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.jdbc.use_get_generated_keys</literal>
+                        </entry>
+                        <entry>
+                            Habilita el uso de <literal>PreparedStatement.getGeneratedKeys()</literal>
+                            de JDBC3 para traer claves generadas nativamente despu&#x00e9;s de insertar.
+                            Requiere un driver JDBC3+ y un JRE1.4+. Establ&#x00e9;cela a false si tu
+                            driver tiene problemas con los generadores de identificador de Hibernate.
+                            Por defecto, se intenta determinar las capacidades del driver usando los
+                            metadatos de conexi&#x00f3;n.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>true|false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.connection.provider_class</literal>
+                        </entry>
+                        <entry>
+                            EL nombre de clase de un <literal>ConnectionProvider</literal> personalizado
+                            que provea conexiones JDBC a Hibernate.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>classname.of.ConnectionProvider</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                    <entry>
+                        <literal>hibernate.connection.isolation</literal>
+                    </entry>
+                    <entry>
+                        Establece el nivel de aislamiento de transacci&#x00f3;n JDBC.
+                        Comprueba <literal>java.sql.Connection</literal> para valores
+                        significativos pero observa que la mayor&#x00ed;a de las bases de
+                        datos no soportan todos los niveles de aislamiento.
+                        <para>
+                            <emphasis role="strong">eg.</emphasis> 
+                            <literal>1, 2, 4, 8</literal>
+                        </para>
+                    </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.connection.autocommit</literal>
+                        </entry>
+                        <entry>
+                            Habilita compromiso autom&#x00e1;tico (autocommit) para
+                            las conexiones JDBC en pool (no recomendado).
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.connection.release_mode</literal>
+                        </entry>
+                        <entry>
+                            Especifica cu&#x00e1;ndo Hibernate debe liberar las conexiones JDBC.
+                            Por defecto, una conexi&#x00f3;n JDBC es retenida hasta que la sesi&#x00f3;n
+                            es cerrada expl&#x00ed;citamente o desconectada. Para un datasource JTA
+                            del servidor de aplicaciones, debes usar <literal>after_statement</literal>
+                            para liberar agresivamente las conexiones despu&#x00e9;s de cada llamada
+                            JDBC. Para una conexi&#x00f3;n no JTA, frecuentemente tiene sentido liberar
+                            la conexi&#x00f3;n al final de cada transacci&#x00f3;n, usando
+                            <literal>after_transaction</literal>. <literal>auto</literal> eligir&#x00e1;
+                            <literal>after_statement</literal> para las estrategias JTA o CMT
+                            de transacci&#x00f3;n y <literal>after_transaction</literal> para la
+                            estrategia JDBC de transacci&#x00f3;n.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>on_close</literal> (por defecto)| <literal>after_transaction</literal> |
+                                <literal>after_statement</literal> | <literal>auto</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                    <entry>
+                        <literal>hibernate.connection.<emphasis>&lt;propertyName&gt;</emphasis></literal>
+                    </entry>
+                    <entry>
+                        Pasa la propiedad JDBC <literal>propertyName</literal>
+                        a <literal>DriverManager.getConnection()</literal>.
+                    </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.jndi.<emphasis>&lt;propertyName&gt;</emphasis></literal>
+                        </entry>
+                        <entry>
+                            Pasa la propiedad <literal>propertyName</literal>
+                            a <literal>InitialContextFactory</literal> de JNDI.
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <table frame="topbot" id="configuration-cache-properties" revision="7">
+            <title>Propiedades de Cach&#x00e9; de Hibernate</title>
+            <tgroup cols="2">
+                <colspec colname="c1" colwidth="1*"/>
+                <colspec colname="c2" colwidth="1*"/>
+                <thead>
+                    <row>
+                        <entry>Nombre de propiedad</entry>
+                        <entry>Prop&#x00f3;sito</entry>
+                    </row>
+                </thead>
+                <tbody>
+                     <row>
+                        <entry>
+                            <literal>hibernate.cache.provider_class</literal>
+                        </entry>
+                        <entry>
+                            El nombre de clase de un <literal>CacheProvider</literal> personalizado.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>classname.of.CacheProvider</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.cache.use_minimal_puts</literal>
+                        </entry>
+                        <entry>
+                            Optimiza la operaci&#x00f3;n del cach&#x00e9; de segundo nivel
+                            para minimizar escrituras, al costo de lecturas m&#x00e1;s frecuentes.
+                            Esto es m&#x00e1;s &#x00fa;til para cach&#x00e9;s en cluster y,
+                            en Hibernate3, est&#x00e1; habilitado por defecto para implementaciones
+                            de cach&#x00e9; en cluster.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>true|false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.cache.use_query_cache</literal>
+                        </entry>
+                        <entry>
+                            Habilita el cach&#x00e9; de lectura, consultas individuales todav&#x00ed;a
+                            tienen que ponerse cachables.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>true|false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.cache.use_second_level_cache</literal>
+                        </entry>
+                        <entry>
+                            Puede ser usado para deshabilitar completamente el cach&#x00e9;
+                            de segundo nivel, que est&#x00e1; habilitado por defecto para clases
+                            que especifican un mapeo <literal>&lt;cache&gt;</literal>.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>true|false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.cache.query_cache_factory</literal>
+                        </entry>
+                        <entry>
+                            El nombre de clase de una interface <literal>QueryCache</literal>
+                            personalizada, por defecto al <literal>StandardQueryCache</literal>
+                            prefabricado.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>classname.of.QueryCache</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.cache.region_prefix</literal>
+                        </entry>
+                        <entry>
+                            Un prefijo a usar para los nombres de regi&#x00f3;n
+                            del cach&#x00e9; de segundo nivel.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>prefix</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.cache.use_structured_entries</literal>
+                        </entry>
+                        <entry>
+                            Fuerza a Hibernate a almacenar los datos en el cach&#x00e9;
+                            de segundo nivel en un formato m&#x00e1;s amigable al humano.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis>
+                                <literal>true|false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <table frame="topbot" id="configuration-transaction-properties" revision="8">
+            <title>Propiedades de Transacci&#x00f3;n de Hibernate</title>
+            <tgroup cols="2">
+                <colspec colname="c1" colwidth="1*"/>
+                <colspec colname="c2" colwidth="1*"/>
+                <thead>
+                    <row>
+                        <entry>Nombre de propiedad</entry>
+                        <entry>Prop&#x00f3;sito</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>
+                            <literal>hibernate.transaction.factory_class</literal>
+                        </entry>
+                        <entry>
+                            El nombre de clase de un <literal>TransactionFactory</literal>
+                            a usar con la API de <literal>Transaction</literal> de Hibernate
+                            (por defectoa <literal>JDBCTransactionFactory</literal>).
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>classname.of.TransactionFactory</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>jta.UserTransaction</literal>
+                        </entry>
+                        <entry>
+                            Un nombre JNDI usado por <literal>JTATransactionFactory</literal> para
+                            obtener la <literal>UserTransaction</literal> JTA del servidor
+                            de aplicaciones.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>jndi/composite/name</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.transaction.manager_lookup_class</literal>
+                        </entry>
+                        <entry>
+                            El nombre de clase de un <literal>TransactionManagerLookup</literal>
+                            requerido cuando el chach&#x00e9; a nivel de JVM est&#x00e1;
+                            habilitado o cuando se usa un generador alto/bajo en un
+                            entorno JTA.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>classname.of.TransactionManagerLookup</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.transaction.flush_before_completion</literal>
+                        </entry>
+                        <entry>
+                            De habilitarse, la sesi&#x00f3;n se limpiar&#x00e1; (flushed)
+                            autom&#x00e1;ticamente durante la fase previa a la compleci&#x00f3;n
+                            de la transacci&#x00f3;n. (Muy &#x00fa;til cuando se usa Hibernate
+                            con CMT).
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.transaction.auto_close_session</literal>
+                        </entry>
+                        <entry>
+                            De habilitarse, la sesi&#x00f3;n ser&#x00e1; cerrada autom&#x00e1;ticamente
+                            durante la fase posterior a la compleci&#x00f3;n de la transacci&#x00f3;n.
+                            (Muy &#x00fa;til cuando se usa Hibernate con CMT).
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <table frame="topbot" id="configuration-misc-properties" revision="7">
+            <title>Propiedades Miscel&#x00e1;neas</title>
+            <tgroup cols="2">
+                <colspec colname="c1" colwidth="1*"/>
+                <colspec colname="c2" colwidth="1*"/>
+                <thead>
+                    <row>
+                        <entry>Nombre de propiedad</entry>
+                        <entry>Prop&#x00f3;sito</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>
+                            <literal>hibernate.query.factory_class</literal>
+                        </entry>
+                        <entry>
+                            Elige la implementaci&#x00f3;n de parser HQL.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>org.hibernate.hql.ast.ASTQueryTranslatorFactory</literal> or
+                                <literal>org.hibernate.hql.classic.ClassicQueryTranslatorFactory</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.query.substitutions</literal>
+                        </entry>
+                        <entry>
+                            Mapeos de s&#x00ed;mbolos en consultas Hibernate a 
+                            s&#x00ed;mbolos SQL. (los s&#x00ed;mbolos puedem ser
+                            nombres de funci&#x00f3;n o literales, por ejemplo).
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.hbm2ddl.auto</literal>
+                        </entry>
+                        <entry>
+                            Exporta autom&#x00e1;ticamente DDL de esquema cuando
+                            al crear la <literal>SessionFactory</literal>.
+                            Con <literal>create-drop</literal>, el esquema de
+                            base de datos ser&#x00e1; desechado cuando la
+                            <literal>SessionFactory</literal> se cierre expl&#x00ed;citamente.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>update</literal> | <literal>create</literal> | <literal>create-drop</literal>
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            <literal>hibernate.cglib.use_reflection_optimizer</literal>
+                        </entry>
+                        <entry>
+                            Habilita el uso de CGLIB en vez de reflecc&#x00f3;n en tiempo de
+                            ejecuci&#x00f3;n (propiedad a nivel de sistema). La reflecci&#x00f3;n
+                            a veces puede ser &#x00fa;til ante la aparici&#x00f3;n de problemas.
+                            Observa que Hibernate siempre requiere CGLIB incluso si desactivas
+                            el optimizador. No puedes establecer esta propiedad en
+                            <literal>hibernate.cfg.xml</literal>.
+                            <para>
+                                <emphasis role="strong">ej.</emphasis> 
+                                <literal>true</literal> | <literal>false</literal>
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <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. 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>
+
+            <table frame="topbot" id="sql-dialects" revision="2">
+                <title>Dialectos SQL de Hibernate(<literal>hibernate.dialect</literal>)</title>
+                <tgroup cols="2">
+                    <colspec colwidth="1*"/>
+                    <colspec colwidth="2.5*"/>
+                    <thead>
+                        <row>
+                            <entry>RDBMS</entry>
+                            <entry>Dialecto</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry>DB2</entry> <entry><literal>org.hibernate.dialect.DB2Dialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>DB2 AS/400</entry> <entry><literal>org.hibernate.dialect.DB2400Dialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>DB2 OS390</entry> <entry><literal>org.hibernate.dialect.DB2390Dialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>PostgreSQL</entry> <entry><literal>org.hibernate.dialect.PostgreSQLDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>MySQL</entry> <entry><literal>org.hibernate.dialect.MySQLDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>MySQL con InnoDB</entry> <entry><literal>org.hibernate.dialect.MySQLInnoDBDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>MySQL con MyISAM</entry> <entry><literal>org.hibernate.dialect.MySQLMyISAMDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Oracle (cualquier versi&#x00f3;n)</entry> <entry><literal>org.hibernate.dialect.OracleDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Oracle 9i/10g</entry> <entry><literal>org.hibernate.dialect.Oracle9Dialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Sybase</entry> <entry><literal>org.hibernate.dialect.SybaseDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Sybase Anywhere</entry> <entry><literal>org.hibernate.dialect.SybaseAnywhereDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Microsoft SQL Server</entry> <entry><literal>org.hibernate.dialect.SQLServerDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>SAP DB</entry> <entry><literal>org.hibernate.dialect.SAPDBDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Informix</entry> <entry><literal>org.hibernate.dialect.InformixDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>HypersonicSQL</entry> <entry><literal>org.hibernate.dialect.HSQLDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Ingres</entry> <entry><literal>org.hibernate.dialect.IngresDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Progress</entry> <entry><literal>org.hibernate.dialect.ProgressDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Mckoi SQL</entry> <entry><literal>org.hibernate.dialect.MckoiDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Interbase</entry> <entry><literal>org.hibernate.dialect.InterbaseDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Pointbase</entry> <entry><literal>org.hibernate.dialect.PointbaseDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>FrontBase</entry> <entry><literal>org.hibernate.dialect.FrontbaseDialect</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Firebird</entry> <entry><literal>org.hibernate.dialect.FirebirdDialect</literal></entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+
+        </sect2>
+
+        <sect2 id="configuration-optional-outerjoin" revision="4">
+            <title>Recuperaci&#x00f3;n por Uni&#x00f3;n Externa (Outer Join Fetching)</title>
+
+            <para>
+                Si tu base de datos soporta uniones externas del estilo ANSI, Oracle o Sybase, la
+                <emphasis>recuperaci&#x00f3;n por uni&#x00f3;n externa</emphasis> aumentar&#x00e1;
+                frecuentemente el rendimiento limitando el n&#x00fa;mero de llamadas a la base de datos
+                (al costo de m&#x00e1;s trabajo posiblemente realizado por la base de datos misma).
+                La recuperaci&#x00f3;n por uni&#x00f3;n externa permite que un grafo completo de objetos
+                conectados por asociaciones muchos-a-uno, uno-a-muchos, muchos-a-muchos y uno-a-uno sea
+                tra&#x00ed;do en una sola <literal>SELECT</literal> SQL.
+            </para>
+
+            <para>
+                La recuperaci&#x00f3;n por uni&#x00f3;n externa puede ser deshabilitada
+                <emphasis>globalmente</emphasis> estableciendo la propiedad
+                <literal>hibernate.max_fetch_depth</literal> a <literal>0</literal>.
+                Un valor de <literal>1</literal> o mayor habilita la recuperaci&#x00f3;n
+                por uni&#x00f3;n externa para asociaciones uno-a-uno y muchos-a-uno que
+                hayan sido mapeadas con <literal>fetch="join"</literal>.
+            </para>
+
+            <para>
+                Ver <xref linkend="performance-fetching"/> para m&#x00e1;s informaci&#x00f3;n.
+            </para>
+
+        </sect2>
+
+        <sect2 id="configuration-optional-binarystreams" revision="1">
+            <title>Flujos Binarios</title>
+
+            <para>
+                Oracle limita el tama&#x00f1;o de arrays de <literal>byte</literal>
+                que puedan ser pasados a/desde su driver JDBC. Si deseas usar instancias
+                grandes de tipo <literal>binary</literal> o <literal>serializable</literal>,
+                debes habilitar <literal>hibernate.jdbc.use_streams_for_binary</literal>.
+                <emphasis>Esta es una propiedad a nivel de sistema solamente.</emphasis>
+            </para>
+
+        </sect2>
+
+        <sect2 id="configuration-optional-cacheprovider" revision="2">
+            <title>Cach&#x00e9; de segundo nivel y de lectura</title>
+
+            <para>
+                Las propiedades prefijadas por <literal>hibernate.cache</literal>
+                te permiten usar un sistema de cach&#x00e9; de segundo nivel
+                en el &#x00e1;mbito de un proceso o cluster con Hibernate.
+                Ver <xref linkend="performance-cache"/> para m&#x00e1;s detalles.
+            </para>
+
+        </sect2>
+
+        <sect2 id="configuration-optional-querysubstitution">
+            <title>Sustituci&#x00f3;n de Lenguaje de Consulta</title>
+
+            <para>
+                Puedes definir nuevos s&#x00ed;mbolos de consulta de Hibernate usando
+                <literal>hibernate.query.substitutions</literal>. Por ejemplo:
+            </para>
+
+            <programlisting>hibernate.query.substitutions true=1, false=0</programlisting>
+
+            <para>
+                causar&#x00ed;a que los s&#x00ed;mbolos <literal>true</literal> y <literal>false</literal> sean
+                traducidos a literales enteros en el SQL generado.
+            </para>
+
+            <programlisting>hibernate.query.substitutions toLowercase=LOWER</programlisting>
+
+            <para>
+                te permitir&#x00ed;a renombrar la funci&#x00f3;n <literal>LOWER</literal> de SQL.
+            </para>
+
+        </sect2>
+
+        <sect2 id="configuration-optional-statistics" revision="2">
+            <title>Hibernate statistics</title>
+
+            <para>
+                Si habilitas <literal>hibernate.generate_statistics</literal>, Hibernate
+                expondr&#x00e1; un n&#x00fa;mero de m&#x00e9;tricas que son &#x00fa;tiles
+                al afinar un sistema en ejecuci&#x00f3;n v&#x00ed;a
+                <literal>SessionFactory.getStatistics()</literal>. Hibernate puede incluso ser
+                configurado para exponer estas estad&#x00ed;sticas v&#x00ed;a JMX. Lee el
+                Javadoc de las interfaces en <literal>org.hibernate.stats</literal>
+                para m&#x00e1;s informaci&#x00f3;n.
+            </para>
+
+        </sect2>
+    </sect1>
+
+    <sect1 id="configuration-logging">
+        <title>Registros de mensajes (Logging)</title>
+
+        <para>
+            Hibernate registra varios eventos usando commons-logging
+            de Apache.
+        </para>
+
+        <para>
+            El servicio de commons-logging saldr&#x00e1; directamente ya sea a
+            Log4J (si incluyes <literal>log4j.jar</literal> in your classpath) o
+            JDK1.4 logging (al ejecutar bajo JDK1.4 o superior). Puedes descargar
+            Log4J desde <literal>http://logging.apache.org</literal>. Para usar
+            Log4J necesitar&#x00e1;s colocar un fichero <literal>log4j.properties</literal>
+            en tu classpath. Un fichero de propiedades de ejemplo se distribuye con
+            Hibernate en el directorio <literal>src/</literal>.
+        </para>
+        
+        <para>
+            Recomendamos fuertemente que te familiarices con los registros de mensajes
+            de Hibernate. Se ha puesto un gran trabajo en hacer los registros de Hibernate
+            tan detallados como se puede, sin hacerlos ilegibles. Es un dispositivo esencial
+            en la resoluci&#x00f3;n de problemas. Las categor&#x00ed;as de registro
+            m&#x00e1;s interesantes son las siguientes:
+        </para>
+        
+            <table frame="topbot" id="log-categories" revision="2">
+                <title>Categor&#x00ed;as de Registro de Hibernate</title>
+                <tgroup cols="2">
+                    <colspec colwidth="1*"/>
+                    <colspec colwidth="2.5*"/>
+                    <thead>
+                        <row>
+                            <entry>Categor&#x00ed;a</entry>
+                            <entry>Funci&#x00f3;n</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry><literal>org.hibernate.SQL</literal></entry>
+                            <entry>Registra todas las sentencias DML de SQL a
+                            medida que se ejecutan</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.type</literal></entry>
+                            <entry>Registra todos los par&#x00e1;metros JDBC</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.tool.hbm2ddl</literal></entry>
+                            <entry>Registra todas las sentencias DDL de SQL a
+                            medida que se ejecutan</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.pretty</literal></entry>
+                            <entry>
+                                Registra el estado de todas las entidades (m&#x00e1;ximo
+                                de 20 entidades) asociadas con la sesi&#x00f3;n en tiempo
+                                de limpieza (flush)
+                            </entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.cache</literal></entry>
+                            <entry>Registra toda la actividad del cach&#x00e9; de segundo nivel</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction</literal></entry>
+                            <entry>Registra la actividad relacionada con la transacci&#x00f3;n</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.jdbc</literal></entry>
+                            <entry>Registra toda adquisici&#x00f3;n de recursos JDBC</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.hql.ast</literal></entry>
+                            <entry>Regista los ASTs de HQL y SQL, as&#x00ed; como
+                            otra informaci&#x00f3;n sobre an&#x00e1;lisis de consultas.</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.secure</literal></entry>
+                            <entry>Registra todas las peticiones de autorizaci&#x00f3;n JAAS</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate</literal></entry>
+                            <entry>
+                                Registra todo (mucha informaci&#x00f3;n, pero muy &#x00fa;til
+                                para la resoluci&#x00f3;n de problemas)
+                            </entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+            
+        <para>
+            Al desarrollar aplicacinoes con Hibernate, casi siempre debes trabajar con
+            <literal>debug</literal> habilitado para la categor&#x0ed;a <literal>org.hibernate.SQL</literal>
+            o, alternativamente, la propiedad <literal>hibernate.show_sql</literal> habilitada.
+        </para>
+                       
+        
+    </sect1>
+
+    <sect1 id="configuration-namingstrategy">
+        <title>Implementando una <literal>NamingStrategy</literal></title>
+
+        <para>
+            La interface <literal>org.hibernate.cfg.NamingStrategy</literal> te permite
+            especificar un "est&#x00e1;ndar de nombrado" para objetos de la base de datos
+            y elementos de esquema.
+        </para>
+
+        <para>
+            Puedes proveer reglas para generar autom&#x00e1;ticamente identificadores de
+            base de datos a partir de identificadores JDBC o para procesar nombres
+            "l&#x00f3;gicos" de columnas y tablas dados en el fichero de mapeo en nombres
+            "f&#x00ed;sicos" de columnas y tablas. Esta funcionalidad ayuda a reducir
+            la verborragia del documento de mapeo, eliminando ruido repetitivo
+            (prefijos <literal>TBL_</literal>, por ejemplo). La estrategia por defecto
+            usada por Hibernate m&#x00ed;nima en absoluto.
+        </para>
+
+        <para>
+            Puedes especificar una estrategia diferente llamando a 
+            <literal>Configuration.setNamingStrategy()</literal> antes de agregar los mapeos:
+        </para>
+
+        <programlisting><![CDATA[SessionFactory sf = new Configuration()
+    .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
+    .addFile("Item.hbm.xml")
+    .addFile("Bid.hbm.xml")
+    .buildSessionFactory();]]></programlisting>
+    
+        <para>
+            <literal>org.hibernate.cfg.ImprovedNamingStrategy</literal>
+            es una estrategia prefabricada que puede ser un punto de
+            partida &#x00fa;til para algunas aplicaciones.
+        </para>
+
+    </sect1>
+
+    <sect1 id="configuration-xmlconfig" revision="2">
+        <title>Fichero de configuraci&#x00f3;n XML</title>
+
+        <para>
+            Un enfoque alternativo de configuraci&#x00f3;n es especificar una
+            configuraci&#x00f3;n completa en un fichero llamado <literal>hibernate.cfg.xml</literal>.
+            Este fichero puede ser usado como un remplazo del fichero <literal>hibernate.properties</literal> o,
+            si ambos est&#x00e1;n presentes, para sobrescribir propiedades.
+        </para>
+
+        <para>
+            El fichero de configuraci&#x00f3;n XML se espera por defecto en la
+            ra&#x00ed;z o tu <literal>CLASSPATH</literal>. He aqu&#x00ed; un ejemplo:
+        </para>
+
+        <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+    "-//Hibernate/Hibernate Configuration DTD//EN"
+    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+    <!-- a SessionFactory instance listed as /jndi/name -->
+    <session-factory
+        name="java:hibernate/SessionFactory">
+
+        <!-- properties -->
+        <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
+        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
+        <property name="show_sql">false</property>
+        <property name="transaction.factory_class">
+            org.hibernate.transaction.JTATransactionFactory
+        </property>
+        <property name="jta.UserTransaction">java:comp/UserTransaction</property>
+
+        <!-- mapping files -->
+        <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 collection="org.hibernate.auction.Item.bids" usage="read-write"/>
+
+    </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+        <para>
+            Como puedes ver, la ventaja de este enfoque es la externalizaci&#x00f3;n de los
+            nombres de los fichero de mapeo a configuraci&#x00f3;n. El
+            <literal>hibernate.cfg.xml</literal> es tambi&#x00e9;n m&#x00e1;s conveniente
+            una vez que hayas afinado el cach&#x00e9; de Hibernate. Observa que elecci&#x00f3;n
+            tuya usar ya sea <literal>hibernate.properties</literal> o
+            <literal>hibernate.cfg.xml</literal>, ambos son equivalentes, excepto por los
+            beneficios de usar la sintaxis XML arriba mencionados.
+        </para>
+
+       <para>
+           Con la configuraci&#x00f3;n XML, arrancar Hibernate es tan simple como
+       </para>
+
+       <programlisting><![CDATA[SessionFactory sf = new Configuration().configure().buildSessionFactory();]]></programlisting>
+
+       <para>
+           Puedes tomar un fichero XML diferente usando
+       </para>
+
+       <programlisting><![CDATA[SessionFactory sf = new Configuration()
+    .configure("catdb.cfg.xml")
+    .buildSessionFactory();]]></programlisting>
+
+    </sect1>
+
+    <sect1 id="configuration-j2ee" revision="1">
+        <title>Integraci&#x00f3; con Servidores de Aplicaciones J2EE</title>
+
+        <para>
+            Hibernate tiene los siguientes puntos de integraci&#x00f3;n con la
+            infraestructura J2EE:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                <emphasis>Datasources manejados por contenedor</emphasis>: Hibernate puede usar
+                conexiones JDBC manejadas por el contenedor y provistas a trav&#x00e9;s de JNDI.
+                Usualmente, un <literal>TransactionManager</literal> compatible con JTA y un
+                <literal>ResourceManager</literal> cuidan del manejo de transacciones (CMT),
+                esp. manejo de transacciones distribu&#x00ed;das a trav&#x00e9;s de varios
+                datasources. Puedes tambi&#x00e9;n, por supuesto, demarcar los l&#x00ed;mites
+                de las transacciones program&#x00e1;ticamente (BMT) o podr&#x00ed;as querer usar
+                para esto la API opcional de <literal>Transaction</literal> de Hibernate para
+                mantener tu c&#x00f3;digo portable.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                <emphasis>Ligamento Autom&#x00e1;tico JNDI</emphasis>: Hibernate puede ligar sus
+                <literal>SessionFactory</literal> a JNDI despu&#x00e9;s del arranque.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                <emphasis>Ligamento de Sesi&#x00f3;n JTA:</emphasis>
+                La <literal>Session</literal> de Hibernate puede ser ligada autom&#x00e1;ticamente
+                al &#x00e1;mbito de transacciones JTA si usas EJBs. Simplemente busca la
+                <literal>SessionFactory</literal> de JNDI y obt&#x00e9;n la <literal>Session</literal>
+                actual. Deja que Hibernate cuide de limpiar y cerrar la <literal>Session</literal>
+                cuando se complete tu transacci&#x00f3;n JTA. La demarcaci&#x00f3;n de transacci&#x00f3;n
+                es declarativa, en descriptores de despliegue de EJB.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                <emphasis>Despliegue JMX:</emphasis> Si tienes un servidor de aplicaciones capaz
+                de JMX (por ejemplo, JBoss AS), puedes optar por desplegar Hibernate como un MBean
+                manejado. Esto te ahorra el c&#x00f3;digo de una l&#x00ed;nea de arranque para
+                construir tu <literal>SessionFactory</literal> desde una <literal>Configuration</literal>.
+                El contenedor arrancar&#x00e1; tu <literal>HibernateService</literal>, e idealmente tambi&#x00e9;n
+                cuidar&#x00e1; de las dependencias entre servicios (El datasource debe estar
+                disponible antes que arranque Hibernate, etc).
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Dependiendo de tu entorno, podr&#x00ed;as tener que establecer la opci&#x00f3;n
+            de configuraci&#x00f3;n <literal>hibernate.connection.aggressive_release</literal>
+            a true si tu servidor de aplicaciones muestra excepciones "connection containment".
+        </para>
+
+        <sect2 id="configuration-optional-transactionstrategy" revision="3">
+            <title>Configuraci&#x00f3;n de la estrategia de transacci&#x00f3;n</title>
+
+            <para>
+                La API de <literal>Session</literal> de Hibernate es independiente de cualquier
+                demarcaci&#x00f3;n de transacci&#x00f3;n en tu arquitectura. Si dejas que Hibernate
+                use JDBC directamente, a trav&#x00e9;s de un pool de conexiones. puedes comenzar y
+                acabar tus transacciones llamando la API de JDBC. Si ejecutas en un servidor de
+                aplicaciones J2EE, podr&#x00e9;as querer usar transacciones manejadas por bean y
+                llamar la API de JTA y <literal>UserTransaction</literal> cuando sea necesario.
+            </para>
+
+            <para>
+                Para mantener tu c&#x00f3;digo portable entre estos dos (y otros) entornos recomendamos la API
+                de <literal>Transaction</literal> de Hibernate, que envuelve y oculta el sistema subyacente.
+                Tienes que especificar una clase f&#x00e1;brica para las instancias de <literal>Transaction</literal>
+                estableciendo la propiedad de configuraci&#x00f3;n <literal>hibernate.transaction.factory_class</literal>
+                de Hibernate.
+            </para>
+
+            <para>
+                Hay tres elecciones est&#x00e1;ndar (prefabricadas):
+            </para>
+
+            <variablelist spacing="compact">
+                <varlistentry>
+                    <term><literal>org.hibernate.transaction.JDBCTransactionFactory</literal></term>
+                    <listitem>
+                        <para>delega a transacciones de base de datos (JDBC) (por defecto)</para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term><literal>org.hibernate.transaction.JTATransactionFactory</literal></term>
+                    <listitem>
+                        <para>
+                            delega a transacciones manejadas por contenedor si una transacci&#x00f3;n
+                            existente est&#x00f3; por debajo en este contexto (ej. m&#x00e9;todo de un
+                            bean de sesi&#x00f3;n EJB), en otro caso una nueva transacci&#x00f3;n es
+                            comenzada y se usan transacciones manejadas por bean.
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term><literal>org.hibernate.transaction.CMTTransactionFactory</literal></term>
+                    <listitem>
+                        <para>delega a transacciones JTA manejadas por contenedor</para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+
+            <para>
+                Puedes definir tambi&#x00e9;n tus propias estrategias de transacci&#x00f3;n
+                (para un servicio de transacci&#x00f3;n CORBA, por ejemplo).
+            </para>
+
+            <para>
+                Algunas funcionalidades en Hibernate (ej, el cach&#x00e9; de segundo nivel, ligamento
+                autom&#x00e1;tico de JTA y Session, etc.) requieren acceso al <literal>TransactionManager</literal>
+                de JTA en un entorno manejado. En un servidor de aplicaciones tienes que especificar
+                c&#x00f3;mo Hibernate debe obtener una referencia al <literal>TransactionManager</literal>,
+                pues J2EE no estandariza un solo mecanismo:
+            </para>
+
+            <table frame="topbot" id="jtamanagerlookup" revision="1">
+                <title>TransactionManagers de JTA</title>
+                <tgroup cols="2">
+                    <colspec colwidth="2.5*"/>
+                    <colspec colwidth="1*"/>
+                    <thead>
+                        <row>
+                            <entry>Transaction Factory</entry>
+                            <entry align="center">Servidor de Aplicaciones</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.JBossTransactionManagerLookup</literal></entry>
+                            <entry align="center">JBoss</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.WeblogicTransactionManagerLookup</literal></entry>
+                            <entry align="center">Weblogic</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.WebSphereTransactionManagerLookup</literal></entry>
+                            <entry align="center">WebSphere</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</literal></entry>
+                            <entry align="center">WebSphere 6</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.OrionTransactionManagerLookup</literal></entry>
+                            <entry align="center">Orion</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.ResinTransactionManagerLookup</literal></entry>
+                            <entry align="center">Resin</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.JOTMTransactionManagerLookup</literal></entry>
+                            <entry align="center">JOTM</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.JOnASTransactionManagerLookup</literal></entry>
+                            <entry align="center">JOnAS</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.JRun4TransactionManagerLookup</literal></entry>
+                            <entry align="center">JRun4</entry>
+                        </row>
+                        <row>
+                            <entry><literal>org.hibernate.transaction.BESTransactionManagerLookup</literal></entry>
+                            <entry align="center">Borland ES</entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+
+        </sect2>
+
+        <sect2 id="configuration-optional-jndi" revision="2">
+            <title><literal>SessionFactory</literal> ligada a JNDI</title>
+
+            <para>
+                Una <literal>SessionFactory</literal> de Hibernate ligada a JNDI puede simplificar
+                la obtenci&#x00f3;n de la f&#x00e1;brica y la creaci&#x00f3;n de nuevas
+                <literal>Session</literal>s. Observa que esto no est&#x00e1; relacionado a un
+                <literal>Datasource</literal> ligado a JNDI, simplemente ambos usan el mismo
+                registro!
+            </para>
+
+            <para>
+                Si deseas tener la <literal>SessionFactory</literal> ligada a un espacio de nombres de JNDI,
+                especifica un nombre (ej. <literal>java:hibernate/SessionFactory</literal>) usando la
+                propiedad <literal>hibernate.session_factory_name</literal>. Si esta propiedad es omitida,
+                la <literal>SessionFactory</literal> no ser&#x00e1; ligada a JNDI (Esto es especialmente
+                &#x00fa;til en entornos con una implementaci&#x00f3; JNDI de s&#x00f3;lo lectura por defecto,
+                ej. Tomcat.)
+            </para>
+
+            <para>
+                Al ligar la <literal>SessionFactory</literal> a JNDI, Hibernate usar&#x00e1; los valores de
+                <literal>hibernate.jndi.url</literal>, <literal>hibernate.jndi.class</literal> para instanciar
+                un contexto inicial. Si &#x00e9;tos no se especifican, se usar&#x00e1; el
+                <literal>InitialContext</literal> por defecto.
+            </para>
+
+            <para>
+                Hibernate colocar&#x00e1; autom&#x00e1;ticamente la <literal>SessionFactory</literal>
+                en JNDI despu&#x00e9;s que llames a <literal>cfg.buildSessionFactory()</literal>.
+                Esto significa que tendr&#x00e1;s al menos esta llamada en alg&#x00fa;n c&#x00f3;digo
+                de arranque (o clase de utilidad) en tu aplicaci&#x00f3;n, a menos qie uses el despliegue
+                JMX con el <literal>HibernateService</literal> (discutido luego).
+            </para>
+
+            <para>
+                Si usas una <literal>SessionFactory</literal> de JNDI, un EJB o cualquier otra
+                clase puede obtener la <literal>SessionFactory</literal> usando una b&#x00fa;squeda
+                JNDI. Observa que esta configuraci&#x00f3;n no es necesaria si usas la clase de ayuda
+                <literal>HibernateUtil</literal> introducida en el cap&#x00ed;tulo uno, que act&#x00fa;a
+                como un registro Singleton. Sin embargo, <literal>HibernateUtil</literal> es m&#x00e1;s
+                com&#x00fa;n en un entorno no manejado.
+            </para>
+
+        </sect2>
+
+        <sect2 id="configuration-j2ee-currentsession" revision="1">
+            <title>Ligado autom&#x00e1;tico de JTA y Session</title>
+
+            <para>
+                Para entornos no manejados hemos sugerido <literal>HibernateUtil</literal> con una
+                <literal>SessionFactory</literal> est&#x00e1;tica, y administraci&#x00f3;n de la
+                <literal>Session</literal> de Hibernate. Este enfoque no es f&#x00e1;cil de usar
+                en un entorno EJB, al poder ejecutarse muchos EJBs dentro de la misma transacci&#x00f3;n
+                pero no en la misma hebra. Recomendados que ligues la <literal>SessionFactory</literal>
+                a JNDI en un entorno manejado.
+            </para>
+
+            <para>
+                En vez de rodar tu propia utilidad de <literal>ThreadLocal</literal>,
+                usa el m&#x00e9;todo <literal>getCurrentSession()</literal> en la
+                <literal>SessionFactory</literal> para obtener una <literal>Session</literal>
+                de Hibernate. Si no hubiese una <literal>Session</literal> de Hibernate en la
+                transacci&#x00f3;n JTA actual, se arrancar&#x00e1; y asignar&#x00e1; una.
+                Ambas opciones de configuraci&#x00f3;n <literal>hibernate.transaction.flush_before_completion</literal>
+                y <literal>hibernate.transaction.auto_close_session</literal>, ser&#x00e1;n establecidas
+                autom&#x00e1;ticamente para cada <literal>Session</literal> que obtengas con
+                <literal>getCurrentSession()</literal>, de modo que &#x00e9;stas ser&#x00e1;n
+                limpiadas (flushed) y cerradas autom&#x00e1;ticamente cuando el contenedor complete
+                las transacciones JTA.
+            </para>
+
+            <para>
+                Si tu, por ejemplo, usas el patr&#x00f3;n de dise&#x00f1;o DAO para escribir tu
+                capa de persistencia, todos los DAO's buscan la <literal>SessionFactory</literal>
+                cuando se necesite y abren la sesi&#x00f3;n "actual". No hay necesidad de pasar
+                las instancias de <literal>SessionFactory</literal> o <literal>Session</literal>
+                alrededor entre el c&#x00f3;digo de control y el c&#x00f3;digo DAO.
+            </para>
+
+        </sect2>
+
+        <sect2 id="configuration-j2ee-jmx" revision="1">
+            <title>Despliegue JMX</title>
+
+            <para>
+                La l&#x00ed;nea <literal>cfg.buildSessionFactory()</literal> todav&#x00ed;a tiene
+                que ser ejecutada en algun sitio para obtener una <literal>SessionFactory</literal>
+                en JNDI. Puedes hacer esto bien en un bloque inicializador <literal>static</literal>
+                (como aquel en <literal>HibernateUtil</literal>) o bien despliegas Hibernate como un
+                <emphasis>servicio manejado</emphasis>.
+            </para>
+
+            <para>
+                Hibernate se distribuye con <literal>org.hibernate.jmx.HibernateService</literal>
+                para despliegue en un servidor de aplicaciones con capacidades JMX, como JBoss AS.
+                El despliegue y la configurac&#x00f3;n reales son espec&#x00ed;ficos del vendedor.
+                He aqu&#x00ed; un <literal>jboss-service.xml</literal> de ejemplo para JBoss 4.0.x:
+            </para>
+
+            <programlisting><![CDATA[<?xml version="1.0"?>
+<server>
+
+<mbean code="org.hibernate.jmx.HibernateService"
+    name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
+
+    <!-- Required services -->
+    <depends>jboss.jca:service=RARDeployer</depends>
+    <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
+
+    <!-- Bind the Hibernate service to JNDI -->
+    <attribute name="JndiName">java:/hibernate/SessionFactory</attribute>
+
+    <!-- Datasource settings -->
+    <attribute name="Datasource">java:HsqlDS</attribute>
+    <attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>
+
+    <!-- Transaction integration -->
+    <attribute name="TransactionStrategy">
+        org.hibernate.transaction.JTATransactionFactory</attribute>
+    <attribute name="TransactionManagerLookupStrategy">
+        org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
+    <attribute name="FlushBeforeCompletionEnabled">true</attribute>
+    <attribute name="AutoCloseSessionEnabled">true</attribute>
+
+    <!-- Fetching options -->
+    <attribute name="MaximumFetchDepth">5</attribute>
+
+    <!-- Second-level caching -->
+    <attribute name="SecondLevelCacheEnabled">true</attribute>
+    <attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
+    <attribute name="QueryCacheEnabled">true</attribute>
+
+    <!-- Logging -->
+    <attribute name="ShowSqlEnabled">true</attribute>
+
+    <!-- Mapping files -->
+    <attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>
+
+</mbean>
+
+</server>]]></programlisting>
+
+            <para>
+                Este fichero es desplegado en un directorio llamado <literal>META-INF</literal> y
+                empaquetado en un fichero JAR con la extensi&#x00f3;n <literal>.sar</literal>
+                (fichero de servicio). Tambi&#x00e9;n necesitas empaquetar Hibernate, sus bibliotecas
+                de terceros requeridas, tus clases persistentes compiladas, as&#x00ed; como tus ficheros de mapeo
+                en el mismo fichero. Tus beans de empresa (usualmente beans de sesi&#x00f3;n) pueden ser
+                mantenidos en su propio fichero JAR, pero debes incluir este fichero EJB JAR en el fichero
+                de servicio principal para obtener una unidad desplegable (en caliente). Consulta la documentaci&#x00f3;n
+                de JBoss AS para m&#x00e1;s informaci&#x00f3;n sobre el servicio JMX y despliegue de EJB.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/events.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/events.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/events.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/events.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,233 @@
+<chapter id="events">
+    <title>Interceptores y eventos</title>
+
+    <para>
+        Frecuentemente es &#x00fa;til para la aplicaci&#x00f3;n reaccionar a ciertos eventos que ocurran dentro de Hibernate.
+        Esto permite la implementaci&#x00f3;n de ciertos tipos de funcionalidade gen&#x00e9;rica, y extensi&#x00f3;n de la
+        funcionalidad de Hibernate.
+    </para>
+
+    <sect1 id="objectstate-interceptors" revision="1">
+        <title>Interceptores</title>
+
+        <para>
+            La interface <literal>Interceptor</literal> provee callbacks desde la sesi&#x00f3;n a la aplicaci&#x00f3;n
+            permitiendo a &#x00e9;sta &#x00fa;ltima inspeccionar y/o manipular las propiedades de un objeto persistente
+            antes que sea salvado, actualizado, borrado o cargado. Un uso posible de esto es seguir la pista
+            de informaci&#x00f3;n de auditor&#x00ed;a. Por ejemplo, el siguiente <literal>Interceptor</literal> establece
+            autom&#x00e1;ticamente el <literal>createTimestamp</literal> cuando un <literal>Auditable</literal> es
+            creado y actualiza la propiedad <literal>lastUpdateTimestamp</literal> cuando un
+            <literal>Auditable</literal> es acutalizado.
+        </para>
+
+        <programlisting><![CDATA[package org.hibernate.test;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.hibernate.Interceptor;
+import org.hibernate.type.Type;
+
+public class AuditInterceptor implements Interceptor, Serializable {
+
+    private int updates;
+    private int creates;
+
+    public void onDelete(Object entity,
+                         Serializable id,
+                         Object[] state,
+                         String[] propertyNames,
+                         Type[] types) {
+        // do nothing
+    }
+
+    public boolean onFlushDirty(Object entity,
+                                Serializable id,
+                                Object[] currentState,
+                                Object[] previousState,
+                                String[] propertyNames,
+                                Type[] types) {
+
+        if ( entity instanceof Auditable ) {
+            updates++;
+            for ( int i=0; i < propertyNames.length; i++ ) {
+                if ( "lastUpdateTimestamp".equals( propertyNames[i] ) ) {
+                    currentState[i] = new Date();
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public boolean onLoad(Object entity,
+                          Serializable id,
+                          Object[] state,
+                          String[] propertyNames,
+                          Type[] types) {
+        return false;
+    }
+
+    public boolean onSave(Object entity,
+                          Serializable id,
+                          Object[] state,
+                          String[] propertyNames,
+                          Type[] types) {
+
+        if ( entity instanceof Auditable ) {
+            creates++;
+            for ( int i=0; i<propertyNames.length; i++ ) {
+                if ( "createTimestamp".equals( propertyNames[i] ) ) {
+                    state[i] = new Date();
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public void postFlush(Iterator entities) {
+        System.out.println("Creations: " + creates + ", Updates: " + updates);
+    }
+
+    public void preFlush(Iterator entities) {
+        updates=0;
+        creates=0;
+    }
+
+    ...
+
+}]]></programlisting>
+
+        <para>
+            El interceptor podr&#x00ed;a ser especificado cuando se crea la sesi&#x00f3;n:
+        </para>
+
+        <programlisting><![CDATA[Session session = sf.openSession( new AuditInterceptor() );]]></programlisting>
+
+        <para>
+            Puedes adem&#x00e1;s establecer un interceptor a un nivel global, usando la <literal>Configuration</literal>:
+        </para>
+    
+        <programlisting><![CDATA[new Configuration().setInterceptor( new AuditInterceptor() );]]></programlisting>
+
+    </sect1>
+
+     <sect1 id="objectstate-events" revision="2">
+        <title>Sistema de eventos</title>
+
+        <para>
+            Si tienes que reaccionar a eventos particulares en tu capa de persistencia, puedes tambi&#x00e9;n la
+            arquitectura de <emphasis>eventos</emphasis> de Hibernate3. El sistema de eventos puede ser usado
+            en adici&#x00f3;n o como un remplazo a los interceptores.
+        </para>
+
+        <para>
+            Esencialmente todos los m&#x00e9;todos de la interface <literal>Session</literal> se correlacionan
+            con un evento. Tienes un <literal>LoadEvent</literal>, un <literal>FlushEvent</literal>, etc
+            (consulta el DTD del fichero de configuraci&#x00f3;n XML o el paquete <literal>org.hibernate.event</literal>
+            para la lista completa de tipos de evento definidos). Cuando se hace una petici&#x00f3;n de uno de estos
+            m&#x00e9;todos, la <literal>Session</literal> de Hibernate genera un evento apropiado y se lo pasa
+            al oyente (listener) de eventos configurado para ese tipo. De f&#x00e1;brica, estos oyentes implementan
+            el mismo procesamiento en los que siempre resultan aquellos m&#x00e9;todos. Sin embargo, eres libre de
+            implementar una personalizaci&#x00f3;n de una de las interfaces oyentes (es decir, el
+            <literal>LoadEvent</literal>  es procesado por la implementaci&#x00f3;n registrada de la interface
+            <literal>LoadEventListener</literal>), en cuyo caso su implementaci&#x00f3;n ser&#x00ed;a responsable
+            de procesar cualquier petici&#x00f3;n <literal>load()</literal> hecha a la <literal>Session</literal>.
+        </para>
+
+        <para>
+            Los oyentes deben ser considerados efectivamente singletons; quiere decir, que son compartidos
+            entre las peticiones, y por lo tanto no guardan ning&#x00fa;n estado en variables de instancia.
+        </para>
+
+        <para>
+            Un oyente personalizado debe implementar la interface apropiada para el evento que quiere procesar y/o
+            extender una de las clases base de conveniencia (o incluso los oyentes de eventos por defecto
+            usados por Hibernate de f&#x00e1;brica al ser &#x00e9;stos declarados non-final para este prop&#x00f3;sito). Los
+            oyentes personalizados pueden ser registrados program&#x00e1;ticamente a trav&#x00e9;s del objeto
+            <literal>Configuration</literal>, o especificados en el XML de configuraci&#x00f3;n de Hibernate
+            (la declaraci&#x00f3;n declarativa a trav&#x00e9;s del fichero de propiedades no est&#x00e1; soportada).
+            He aqu&#x00ed; un ejemplo de un oyente personalizado de eventos load:
+        </para>
+
+        <programlisting><![CDATA[public class MyLoadListener extends DefaultLoadEventListener {
+    // this is the single method defined by the LoadEventListener interface
+    public Object onLoad(LoadEvent event, LoadEventListener.LoadType loadType)
+            throws HibernateException {
+        if ( !MySecurity.isAuthorized( event.getEntityClassName(), event.getEntityId() ) ) {
+            throw MySecurityException("Unauthorized access");
+        }
+        return super.onLoad(event, loadType);
+    }
+}]]></programlisting>
+
+        <para>
+            Necesitas adem&#x00e1;s una entrada de configuraci&#x00f3;n dici&#x00e9;ndole a Hibernate que use el
+            oyente en vez del oyente por defecto:
+        </para>
+
+<programlisting><![CDATA[<hibernate-configuration>
+    <session-factory>
+        ...
+        <listener type="load" class="MyLoadListener"/>
+    </session-factory>
+</hibernate-configuration>]]></programlisting>
+
+        <para>
+            En cambio, puedes registrarlo program&#x00e1;ticamente:
+        </para>
+
+        <programlisting><![CDATA[Configuration cfg = new Configuration();
+cfg.getSessionEventListenerConfig().setLoadEventListener( new MyLoadListener() );]]></programlisting>
+
+        <para>
+            Los oyentes registrados declarativamente no pueden compartir instancias. Si el mismo nombre de clase es
+            usado en m&#x00fa;ltiples elementos <literal>&lt;listener/&gt;</literal>, cada referencia resultar&#x00e1; en una instancia
+            separada de esa clase. Si necesitas la capacidad de compartir instancias de oyentes entre tipos de oyente
+            debes usar el enfoque de registraci&#x00f3;n program&#x00e1;tica.
+        </para>
+
+        <para>
+            &#x00bf;Por qu&#x00e9; implementar una interface y definir el tipo espc&#x00ed;fico durante la configuraci&#x00f3;n?
+            Bueno, una implementaci&#x00f3;n de oyente podr&#x00ed;a implementar m&#x00fa;ltiples interfaces de oyente
+            de eventos. Teniendo el tipo definido adicionalmente durante la registraci&#x00f3;n lo hace m&#x00e1;s
+            f&#x00e1;cil para activar o desactivar oyentes personalizados durante la configuraci&#x00f3;n.
+        </para>
+
+    </sect1>
+    
+    <sect1 id="objectstate-decl-security">
+        <title>Seguridad declarativa de Hibernate</title>
+        <para>
+            Usualmente, la seguridad declarativa en aplicaciones Hibernate es manejada en una capa  de fachada
+            de sesi&#x00f3;n. Ahora, Hibernate3 permite que ciertas acciones sean permitidas v&#x00ed;a JACC, y autorizadas v&#x00ed;a
+            JAAS. Esta en una funcionalidad opcional constru&#x00ed;da encima de la arquitectura de eventos.
+        </para>
+        
+        <para>
+            Primero, debes configurar los oyentes de eventos apropiados, para habilitar el uso de
+            autorizaci&#x00f3;n JAAS.
+        </para>
+        
+        <programlisting><![CDATA[<listener type="pre-delete" class="org.hibernate.secure.JACCPreDeleteEventListener"/>
+<listener type="pre-update" class="org.hibernate.secure.JACCPreUpdateEventListener"/>
+<listener type="pre-insert" class="org.hibernate.secure.JACCPreInsertEventListener"/>
+<listener type="pre-load" class="org.hibernate.secure.JACCPreLoadEventListener"/>]]></programlisting>
+
+        <para>
+            Seguido, a&#x00fa;n en <literal>hibernate.cfg.xml</literal>, liga los permisos a roles:
+        </para>
+        
+        <programlisting><![CDATA[<grant role="admin" entity-name="User" actions="insert,update,read"/>
+<grant role="su" entity-name="User" actions="*"/>]]></programlisting>
+        
+        <para>
+            Los nombres de role son los roles entendidos por tu proveedor de JACC.
+        </para>
+       
+    </sect1>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_mappings.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/example_mappings.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_mappings.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_mappings.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,654 @@
+<chapter id="example-mappings">
+    <title>Ejemplo: Varios Mapeos</title>
+    
+    <para>
+        Este cap&#x00ed;tulo muestra mapeos de asociaciones m&#x00e1;s complejos.
+    </para>
+    
+    <sect1 id="example-mappings-emp">
+        <title>Empleador/Empleado</title>
+
+        <para>
+            El siguiente modelo de la relaci&#x00f3;n entre <literal>Employer</literal> y <literal>Employee</literal> 
+            usa una clase de entidad real (<literal>Employment</literal>) para representar la asociaci&#x00f3;n.
+            Esto se ha hecho esto porque podr&#x00ed;a haber m&#x00e1;s de un per&#x00ed;odo de empleo para los mismos dos participantes.
+            Se usan componentes para modelar valores monetarios y nombres de empleado.
+        </para>
+
+        <mediaobject>
+            <imageobject role="fo">
+                <imagedata fileref="../images/EmployerEmployee.gif" format="GIF" align="center"/>
+            </imageobject>
+            <imageobject role="html">
+                <imagedata fileref="../images/EmployerEmployee.gif" format="GIF" align="center"/>
+            </imageobject>
+        </mediaobject>
+        
+        <para>
+            He aqu&#x00ed; un documento de mapeo posible:
+        </para>
+        
+        <programlisting><![CDATA[<hibernate-mapping>
+        
+    <class name="Employer" table="employers">
+        <id name="id">
+            <generator class="sequence">
+                <param name="sequence">employer_id_seq</param>
+            </generator>
+        </id>
+        <property name="name"/>
+    </class>
+
+    <class name="Employment" table="employment_periods">
+
+        <id name="id">
+            <generator class="sequence">
+                <param name="sequence">employment_id_seq</param>
+            </generator>
+        </id>
+        <property name="startDate" column="start_date"/>
+        <property name="endDate" column="end_date"/>
+
+        <component name="hourlyRate" class="MonetaryAmount">
+            <property name="amount">
+                <column name="hourly_rate" sql-type="NUMERIC(12, 2)"/>
+            </property>
+            <property name="currency" length="12"/>
+        </component>
+
+        <many-to-one name="employer" column="employer_id" not-null="true"/>
+        <many-to-one name="employee" column="employee_id" not-null="true"/>
+
+    </class>
+
+    <class name="Employee" table="employees">
+        <id name="id">
+            <generator class="sequence">
+                <param name="sequence">employee_id_seq</param>
+            </generator>
+        </id>
+        <property name="taxfileNumber"/>
+        <component name="name" class="Name">
+            <property name="firstName"/>
+            <property name="initial"/>
+            <property name="lastName"/>
+        </component>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+    <para>
+        Y he aqu&#x00ed; el esquema de tablas generado por <literal>SchemaExport</literal>.
+    </para>
+
+    <programlisting><![CDATA[create table employers (
+    id BIGINT not null, 
+    name VARCHAR(255), 
+    primary key (id)
+)
+
+create table employment_periods (
+    id BIGINT not null,
+    hourly_rate NUMERIC(12, 2),
+    currency VARCHAR(12), 
+    employee_id BIGINT not null, 
+    employer_id BIGINT not null, 
+    end_date TIMESTAMP, 
+    start_date TIMESTAMP, 
+    primary key (id)
+)
+
+create table employees (
+    id BIGINT not null, 
+    firstName VARCHAR(255), 
+    initial CHAR(1), 
+    lastName VARCHAR(255), 
+    taxfileNumber VARCHAR(255), 
+    primary key (id)
+)
+
+alter table employment_periods 
+    add constraint employment_periodsFK0 foreign key (employer_id) references employers
+alter table employment_periods 
+    add constraint employment_periodsFK1 foreign key (employee_id) references employees
+create sequence employee_id_seq
+create sequence employment_id_seq
+create sequence employer_id_seq]]></programlisting>
+
+    </sect1>
+    
+    <sect1 id="example-mappings-authorwork">
+        <title>Autor/Obra</title>
+
+        <para>
+            Considera el siguiente modelo de las relaciones entre <literal>Work</literal>,
+            <literal>Author</literal> y <literal>Person</literal>. Representamos la relaci&#x00f3;n entre <literal>Work</literal>
+            y <literal>Author</literal> como una asociaci&#x00f3;n muchos-a-muchos. Elegimos representar la relaci&#x00f3;n entre
+            <literal>Author</literal> y <literal>Person</literal> como una asociaci&#x00f3;n uno-a-uno. Otra posibilidad
+            hubiese sido que <literal>Author</literal> extendiera <literal>Person</literal>.
+        </para>
+
+        <mediaobject>
+            <imageobject role="fo">
+                <imagedata fileref="../images/AuthorWork.gif" format="GIF" align="center"/>
+            </imageobject>
+            <imageobject role="html">
+                <imagedata fileref="../images/AuthorWork.gif" format="GIF" align="center"/>
+            </imageobject>
+        </mediaobject>
+        
+        <para>
+            El siguiente documento de mapeo representa estas relaciones correctamente:
+        </para>
+        
+        <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="Work" table="works" discriminator-value="W">
+
+        <id name="id" column="id">
+            <generator class="native"/>
+        </id>
+        <discriminator column="type" type="character"/>
+
+        <property name="title"/>
+        <set name="authors" table="author_work">
+            <key column name="work_id"/>
+            <many-to-many class="Author" column name="author_id"/>
+        </set>
+
+        <subclass name="Book" discriminator-value="B">
+            <property name="text"/>
+        </subclass>
+
+        <subclass name="Song" discriminator-value="S">
+            <property name="tempo"/>
+            <property name="genre"/>
+        </subclass>
+
+    </class>
+
+    <class name="Author" table="authors">
+
+        <id name="id" column="id">
+            <!-- The Author must have the same identifier as the Person -->
+            <generator class="assigned"/> 
+        </id>
+
+        <property name="alias"/>
+        <one-to-one name="person" constrained="true"/>
+
+        <set name="works" table="author_work" inverse="true">
+            <key column="author_id"/>
+            <many-to-many class="Work" column="work_id"/>
+        </set>
+
+    </class>
+
+    <class name="Person" table="persons">
+        <id name="id" column="id">
+            <generator class="native"/>
+        </id>
+        <property name="name"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+    <para>
+        Hay cuatro tablas en este mapeo. <literal>works</literal>, <literal>authors</literal> y <literal>persons</literal>
+        tienen los datos de obra, autor y persona respectivamente. <literal>author_work</literal> es una tabla de
+        asociaci&#x00f3;n enlazando autores a obras. He aqu&#x00ed; el esquema de tablas, tal como fue generado por
+        <literal>SchemaExport</literal>.
+    </para>
+
+    <programlisting><![CDATA[create table works (
+    id BIGINT not null generated by default as identity, 
+    tempo FLOAT, 
+    genre VARCHAR(255), 
+    text INTEGER, 
+    title VARCHAR(255), 
+    type CHAR(1) not null, 
+    primary key (id)
+)
+
+create table author_work (
+    author_id BIGINT not null, 
+    work_id BIGINT not null, 
+    primary key (work_id, author_id)
+)
+
+create table authors (
+    id BIGINT not null generated by default as identity, 
+    alias VARCHAR(255), 
+    primary key (id)
+)
+
+create table persons (
+    id BIGINT not null generated by default as identity, 
+    name VARCHAR(255), 
+    primary key (id)
+)
+
+alter table authors 
+    add constraint authorsFK0 foreign key (id) references persons
+alter table author_work 
+    add constraint author_workFK0 foreign key (author_id) references authors
+alter table author_work
+    add constraint author_workFK1 foreign key (work_id) references works]]></programlisting>
+
+    </sect1>
+
+    <sect1 id="example-mappings-customerorderproduct">
+        <title>Cliente/Orden/Producto</title>
+
+        <para>
+            Ahora considera un modelo de las relaciones entre <literal>Customer</literal>,
+            <literal>Order</literal> y <literal>LineItem</literal> y <literal>Product</literal>.
+            Hay una asociaci&#x00f3;n uno-a-muchos entre <literal>Customer</literal> y <literal>Order</literal>,
+            pero, &#x00bf;c&#x00f3;mo deber&#x00ed;amos representar <literal>Order</literal> / <literal>LineItem</literal> / <literal>Product</literal>? 
+            He elegido mapear <literal>LineItem</literal> como una clase de asociaci&#x00f3;n representando la
+            asociaci&#x00f3;n muchos-a-muchos entre <literal>Order</literal> y <literal>Product</literal>. En Hibernate,
+            esto se llama un elemento compuesto.
+        </para>
+
+        <mediaobject>
+            <imageobject role="fo">
+                <imagedata fileref="../images/CustomerOrderProduct.gif" format="GIF" align="center"/>
+            </imageobject>
+            <imageobject role="html">
+                <imagedata fileref="../images/CustomerOrderProduct.gif" format="GIF" align="center"/>
+            </imageobject>
+        </mediaobject>
+        
+        <para>
+            El documento de mapeo:
+        </para>
+        
+        <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="Customer" table="customers">
+        <id name="id">
+            <generator class="native"/>
+        </id>
+        <property name="name"/>
+        <set name="orders" inverse="true">
+            <key column="customer_id"/>
+            <one-to-many class="Order"/>
+        </set>
+    </class>
+
+    <class name="Order" table="orders">
+        <id name="id">
+            <generator class="native"/>
+        </id>
+        <property name="date"/>
+        <many-to-one name="customer" column="customer_id"/>
+        <list name="lineItems" table="line_items">
+            <key column="order_id"/>
+            <list-index column="line_number"/>
+            <composite-element class="LineItem">
+                <property name="quantity"/>
+                <many-to-one name="product" column="product_id"/>
+            </composite-element>
+        </list>
+    </class>
+
+    <class name="Product" table="products">
+        <id name="id">
+            <generator class="native"/>
+        </id>
+        <property name="serialNumber"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+    <para>
+        <literal>customers</literal>, <literal>orders</literal>, <literal>line_items</literal> y
+        <literal>products</literal> tienen los datos de cliente, orden, &#x00ed;tem de l&#x00ed;nea de orden y producto
+        respectivamente. Adem&#x00e1;s <literal>line_items</literal> act&#x00fa;a como una tabla de asociaci&#x00f3;n enlazando
+        &#x00f3;rdenes con productos.
+    </para>
+
+    <programlisting><![CDATA[create table customers (
+    id BIGINT not null generated by default as identity, 
+    name VARCHAR(255), 
+    primary key (id)
+)
+
+create table orders (
+    id BIGINT not null generated by default as identity, 
+    customer_id BIGINT, 
+    date TIMESTAMP, 
+    primary key (id)
+)
+
+create table line_items (
+    line_number INTEGER not null, 
+    order_id BIGINT not null, 
+    product_id BIGINT, 
+    quantity INTEGER, 
+    primary key (order_id, line_number)
+)
+
+create table products (
+    id BIGINT not null generated by default as identity, 
+    serialNumber VARCHAR(255), 
+    primary key (id)
+)
+
+alter table orders 
+    add constraint ordersFK0 foreign key (customer_id) references customers
+alter table line_items
+    add constraint line_itemsFK0 foreign key (product_id) references products
+alter table line_items
+    add constraint line_itemsFK1 foreign key (order_id) references orders]]></programlisting>
+
+    </sect1>
+    
+    <sect1 id="misc">
+        <title>Mapeos miscel&#x00e1;neos de ejemplo</title>
+        
+        <para>
+            Todos estos ejemplos est&#x00e1;n tomados de la bater&#x00ed;a de pruebas de Hibernate.
+            Encontrar&#x00e1;s muchos otros mapeos de ejemplo &#x00fa;tiles all&#x00ed;. Mira en la carpeta
+            <literal>test</literal> de la distribuci&#x00f3;n de Hibernate.
+        </para>
+        
+        <para>POR HACER: poner palabras alrededor de este material</para>
+        
+        <sect2 id="example-mappings-typed-onetone">
+            <title>Asociaci&#x00f3;n uno-a-uno "Tipificada"</title>
+<programlisting><![CDATA[<class name="Person">
+    <id name="name"/>
+    <one-to-one name="address" 
+            cascade="all">
+        <formula>name</formula>
+        <formula>'HOME'</formula>
+    </one-to-one>
+    <one-to-one name="mailingAddress" 
+            cascade="all">
+        <formula>name</formula>
+        <formula>'MAILING'</formula>
+    </one-to-one>
+</class>
+
+<class name="Address" batch-size="2" 
+        check="addressType in ('MAILING', 'HOME', 'BUSINESS')">
+    <composite-id>
+        <key-many-to-one name="person" 
+                column="personName"/>
+        <key-property name="type" 
+                column="addressType"/>
+    </composite-id>
+    <property name="street" type="text"/>
+    <property name="state"/>
+    <property name="zip"/>
+</class>]]></programlisting>
+        </sect2>
+        
+        <sect2 id="example-mappings-composite-key">
+            <title>Ejemplo de clave compuesta</title>
+<programlisting><![CDATA[<class name="Customer">
+
+    <id name="customerId"
+        length="10">
+        <generator class="assigned"/>
+    </id>
+
+    <property name="name" not-null="true" length="100"/>
+    <property name="address" not-null="true" length="200"/>
+
+    <list name="orders"
+            inverse="true"
+            cascade="save-update">
+        <key column="customerId"/>
+        <index column="orderNumber"/>
+        <one-to-many class="Order"/>
+    </list>
+
+</class>
+
+<class name="Order" table="CustomerOrder" lazy="true">
+    <synchronize table="LineItem"/>
+    <synchronize table="Product"/>
+    
+    <composite-id name="id" 
+            class="Order$Id">
+        <key-property name="customerId" length="10"/>
+        <key-property name="orderNumber"/>
+    </composite-id>
+    
+    <property name="orderDate" 
+            type="calendar_date"
+            not-null="true"/>
+    
+    <property name="total">
+        <formula>
+            ( select sum(li.quantity*p.price) 
+            from LineItem li, Product p 
+            where li.productId = p.productId 
+                and li.customerId = customerId 
+                and li.orderNumber = orderNumber )
+        </formula>
+    </property>
+    
+    <many-to-one name="customer"
+            column="customerId"
+            insert="false"
+            update="false" 
+            not-null="true"/>
+        
+    <bag name="lineItems"
+            fetch="join" 
+            inverse="true"
+            cascade="save-update">
+        <key>
+            <column name="customerId"/>
+            <column name="orderNumber"/>
+        </key>
+        <one-to-many class="LineItem"/>
+    </bag>
+    
+</class>
+    
+<class name="LineItem">
+    
+    <composite-id name="id" 
+            class="LineItem$Id">
+        <key-property name="customerId" length="10"/>
+        <key-property name="orderNumber"/>
+        <key-property name="productId" length="10"/>
+    </composite-id>
+    
+    <property name="quantity"/>
+    
+    <many-to-one name="order"
+            insert="false"
+            update="false" 
+            not-null="true">
+        <column name="customerId"/>
+        <column name="orderNumber"/>
+    </many-to-one>
+    
+    <many-to-one name="product"
+            insert="false"
+            update="false" 
+            not-null="true"
+            column="productId"/>
+        
+</class>
+
+<class name="Product">
+    <synchronize table="LineItem"/>
+
+    <id name="productId"
+        length="10">
+        <generator class="assigned"/>
+    </id>
+    
+    <property name="description" 
+        not-null="true" 
+        length="200"/>
+    <property name="price" length="3"/>
+    <property name="numberAvailable"/>
+    
+    <property name="numberOrdered">
+        <formula>
+            ( select sum(li.quantity) 
+            from LineItem li 
+            where li.productId = productId )
+        </formula>
+    </property>
+    
+</class>]]></programlisting>
+        </sect2>
+        
+        <sect2 id="example-mappings-composite-key-manytomany">
+            <title>Muchos-a-muchos con atributo de clave compuesta compartido</title>
+<programlisting><![CDATA[<class name="User" table="`User`">
+    <composite-id>
+        <key-property name="name"/>
+        <key-property name="org"/>
+    </composite-id>
+    <set name="groups" table="UserGroup">
+        <key>
+            <column name="userName"/>
+            <column name="org"/>
+        </key>
+        <many-to-many class="Group">
+            <column name="groupName"/>
+            <formula>org</formula>
+        </many-to-many>
+    </set>
+</class>
+    
+<class name="Group" table="`Group`">
+    <composite-id>
+        <key-property name="name"/>
+        <key-property name="org"/>
+    </composite-id>
+    <property name="description"/>
+    <set name="users" table="UserGroup" inverse="true">
+        <key>
+            <column name="groupName"/>
+            <column name="org"/>
+        </key>
+        <many-to-many class="User">
+            <column name="userName"/>
+            <formula>org</formula>
+        </many-to-many>
+    </set>
+</class>
+]]></programlisting>
+        </sect2>
+
+        <sect2 id="example-mappings-content-discrimination">
+            <title>Discriminaci&#x00f3;n basada en contenido</title>
+<programlisting><![CDATA[<class name="Person"
+    discriminator-value="P">
+    
+    <id name="id" 
+        column="person_id" 
+        unsaved-value="0">
+        <generator class="native"/>
+    </id>
+    
+            
+    <discriminator 
+        type="character">
+        <formula>
+            case 
+                when title is not null then 'E' 
+                when salesperson is not null then 'C' 
+                else 'P' 
+            end
+        </formula>
+    </discriminator>
+
+    <property name="name" 
+        not-null="true"
+        length="80"/>
+        
+    <property name="sex" 
+        not-null="true"
+        update="false"/>
+    
+    <component name="address">
+        <property name="address"/>
+        <property name="zip"/>
+        <property name="country"/>
+    </component>
+    
+    <subclass name="Employee" 
+        discriminator-value="E">
+            <property name="title"
+                length="20"/>
+            <property name="salary"/>
+            <many-to-one name="manager"/>
+    </subclass>
+    
+    <subclass name="Customer" 
+        discriminator-value="C">
+            <property name="comments"/>
+            <many-to-one name="salesperson"/>
+    </subclass>
+    
+</class>]]></programlisting>
+        </sect2>
+
+        <sect2 id="example-mappings-association-alternatekeys" >
+            <title>Asociaciones sobre claves alternativas</title>
+<programlisting><![CDATA[<class name="Person">
+    
+    <id name="id">
+        <generator class="hilo"/>
+    </id>
+    
+    <property name="name" length="100"/>
+    
+    <one-to-one name="address" 
+        property-ref="person"
+        cascade="all"
+        fetch="join"/>
+    
+    <set name="accounts" 
+        inverse="true">
+        <key column="userId"
+            property-ref="userId"/>
+        <one-to-many class="Account"/>
+    </set>
+    
+    <property name="userId" length="8"/>
+
+</class>
+
+<class name="Address">
+
+    <id name="id">
+        <generator class="hilo"/>
+    </id>
+
+    <property name="address" length="300"/>
+    <property name="zip" length="5"/>
+    <property name="country" length="25"/>
+    <many-to-one name="person" unique="true" not-null="true"/>
+
+</class>
+
+<class name="Account">
+    <id name="accountId" length="32">
+        <generator class="uuid.hex"/>
+    </id>
+    
+    <many-to-one name="user"
+        column="userId"
+        property-ref="userId"/>
+    
+    <property name="type" not-null="true"/>
+    
+</class>]]></programlisting>
+        </sect2>
+
+    </sect1>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_parentchild.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/example_parentchild.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_parentchild.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_parentchild.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,362 @@
+<chapter id="example-parentchild">
+    <title>Ejemplo: Padre/Hijo</title>
+
+    <para>
+        Una de las primer&#x00ed;simas cosas que los usuarios nuevos intentan hacer con Hibernate es modelar una relaci&#x00f3;n de
+        tipo padre / hijo. Para esto hay dos enfoques diferentes. Por varias razones, el enfoque m&#x00e1;s conveniente,
+        especialmente para usuarios nuevos, es modelar tanto <literal>Parent</literal> como <literal>Child</literal>
+        como clases de entidad con una asociaci&#x00f3;n <literal>&lt;one-to-many&gt;</literal> desde <literal>Parent</literal>
+        a <literal>Child</literal>. (El enfoque alternativo es declarar el <literal>Child</literal> como un
+        <literal>&lt;composite-element&gt;</literal>.) Ahora, resulta que la sem&#x00e1;ntica por defecto de una asociaci&#x00f3;n
+        uno a muchos (en Hibernate) es mucho menos cercana a la sem&#x00e1;ntica usual de una relaci&#x00f3;n padre / hijo que aquellas
+        de un mapeo de elementos compuestos. Explicaremos c&#x00f3;mo usar una <emphasis>asociaci&#x00f3;n uno a muchos bidireccional
+        con tratamiento en cascada</emphasis> para modelar una relaci&#x00f3;n padre / hijo eficiente y elegantemente.
+        &#x00a1;No es para nada dif&#x00ed;cil!
+    </para>
+    
+    <sect1 id="example-parentchild-collections">
+        <title>Una nota sobre las colecciones</title>
+
+        <para>
+            Se considera que las colecciones de Hibernate son una parte l&#x00f3;gica de la entidad que las posee; nunca de
+            las entidades contenidas. &#x00a1;Esta es una distinci&#x00f3;n crucial! Esto tiene las siguientes consecuencias:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+            <para>
+                Cuando se quita / a&#x00f1;ade un objeto desde / a una colecci&#x00f3;n, se incrementa el n&#x00fa;mero de versi&#x00f3;n del
+                due&#x00f1;o de la colecci&#x00f3;n.
+            </para>
+            </listitem>
+            <listitem>
+            <para>
+                Si un objeto que fue quitado de una colecci&#x00f3;n es una instancia de un tipo de valor (por ejemplo, un
+                elemento compuesto), ese objeta cesar&#x00e1; de ser persistente y su estado ser&#x00e1; completamente quitado de la
+                base de datos. Asimismo, a&#x00f1;adir una instancia de tipo de valor a la colecci&#x00f3;n causar&#x00e1; que su estado
+                sea inmediatamente persistente.
+            </para>
+            </listitem>
+            <listitem>
+            <para>
+                Por otro lado, si se quita una entidad de una colecci&#x00f3;n (una asociaci&#x00f3;n uno-a-muchos o muchos-a-muchos),
+                no ser&#x00e1; borrado, por defecto. Este comportamiento es completamente consistente. &#x00a1;Un cambio en el
+                estado interno de otra entidad no hace desaparecer la entidad asociada! Asimismo, a&#x00f1;adir una entidad a
+                una colecci&#x00f3;n no causa que la entidad se vuelva persistente, por defecto.
+            </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            En cambio, el comportamiento por defecto es que al a&#x00f1;adir una entidad a una colecci&#x00f3;n se crea meramente
+            un enlace entre las dos entidades, mientras que al quitarla se quita el enlace. Esto es muy apropiado para
+            todos los tipos de casos. Donde no es para nada apropiado es en el caso de una relaci&#x00f3;n padre / hijo. donde
+            la vida del hijo est&#x00e1; ligada al ciclo de vida del padre.
+        </para>
+    
+    </sect1>
+
+    <sect1 id="example-parentchild-bidir">
+        <title>Uno-a-muchos bidirectional</title>
+
+        <para>
+            Sup&#x00f3;n que empezamos con una asociaci&#x00f3;n simple <literal>&lt;one-to-many&gt;</literal> desde
+            <literal>Parent</literal> a <literal>Child</literal>.
+        </para>
+
+        <programlisting><![CDATA[<set name="children">
+    <key column="parent_id"/>
+    <one-to-many class="Child"/>
+</set>]]></programlisting>
+    
+        <para>
+            Si ejecut&#x00e1;semos el siguiente c&#x00f3;digo
+        </para>
+
+        <programlisting><![CDATA[Parent p = .....;
+Child c = new Child();
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+    
+        <para>
+            Hibernate publicar&#x00ed;a dos sentencias SQL:
+        </para>
+
+        <itemizedlist>
+        <listitem>
+            <para>un <literal>INSERT</literal> para crear el registro de <literal>c</literal></para>
+        </listitem>
+        <listitem>
+            <para>
+                un <literal>UPDATE</literal> para crear el enlace desde <literal>p</literal> a
+                <literal>c</literal>
+            </para>
+        </listitem>
+        </itemizedlist>
+    
+        <para>
+            Esto no es s&#x00f3;lo ineficiente, sino que adem&#x00e1;s viola cualquier restricci&#x00f3;n <literal>NOT NULL</literal> en la
+            columna <literal>parent_id</literal>. Podemos reparar la violaci&#x00f3;n de restricci&#x00f3;n de nulabilidad
+            especificando <literal>not-null="true"</literal> en el mapeo de la colecci&#x00f3;n:
+        </para>
+
+        <programlisting><![CDATA[<set name="children">
+    <key column="parent_id" not-null="true"/>
+    <one-to-many class="Child"/>
+</set>]]></programlisting>
+    
+        <para>
+            Sin embargo, esta no es la soluci&#x00f3;n recomendada.
+       	</para>
+       	<para>
+            El caso subyacente de este comportamiento es que el enlace (la clave for&#x00e1;nea <literal>parent_id</literal>)
+            de <literal>p</literal> a <literal>c</literal> no es considerado parte del estado del objeto
+            <literal>Child</literal> y por lo tanto no es creada en el <literal>INSERT</literal>. De modo que la
+            soluci&#x00f3;n es hacer el enlace parte del mapeo del <literal>Child</literal>.
+        </para>
+
+        <programlisting><![CDATA[<many-to-one name="parent" column="parent_id" not-null="true"/>]]></programlisting>
+
+        <para>
+            (Necesitamos adem&#x00e1;s a&#x00f1;adir la propiedad <literal>parent</literal> a la clase <literal>Child</literal>.)
+        </para>
+
+        <para>
+            Ahora que la entidad <literal>Child</literal> est&#x00e1; gestionando el estado del enlace, le decimos a la
+            colecci&#x00f3;n que no actualice el enlace. Usamos el atributo <literal>inverse</literal>.
+        </para>
+
+        <programlisting><![CDATA[<set name="children" inverse="true">
+    <key column="parent_id"/>
+    <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+        <para>
+            El siguiente c&#x00f3;digo podr&#x00ed;a ser usado para a&#x00f1;adir un nuevo <literal>Child</literal>
+        </para>
+
+        <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+c.setParent(p);
+p.getChildren().add(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+        <para>
+            Y ahora, &#x00a1;S&#x00f3;lo se publicar&#x00ed;a un <literal>INSERT</literal> de SQL!
+        </para>
+
+        <para>
+            Para ajustar un poco m&#x00e1;s las cosas, podr&#x00ed;amos crear un m&#x00e9;todo <literal>addChild()</literal> en
+            <literal>Parent</literal>.
+        </para>
+
+        <programlisting><![CDATA[public void addChild(Child c) {
+    c.setParent(this);
+    children.add(c);
+}]]></programlisting>
+
+        <para>
+            Ahora, el c&#x00f3;digo para a&#x00f1;adir un <literal>Child</literal> se ve as&#x00ed;
+        </para>
+
+        <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.save(c);
+session.flush();]]></programlisting>
+
+     </sect1>
+     
+     <sect1 id="example-parentchild-cascades">
+         <title>Ciclo de vida en cascada</title>
+     
+         <para>
+             La llamada expl&#x00ed;cita a <literal>save()</literal> es a&#x00fa;n molesta. Apuntaremos a esto usando tratamientos
+             en cascada.
+         </para>
+
+        <programlisting><![CDATA[<set name="children" inverse="true" cascade="all">
+    <key column="parent_id"/>
+    <one-to-many class="Child"/>
+</set>]]></programlisting>
+     
+         <para>
+             Esto simplifica el c&#x00f3;digo anterior a 
+         </para>
+
+        <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = new Child();
+p.addChild(c);
+session.flush();]]></programlisting>
+     
+         <para>
+             Similarmente, no necesitamos iterar los hijos al salvar o borrar un <literal>Parent</literal>.
+             Lo siguiente quita <literal>p</literal> y todos sus hijos de la base de datos.
+         </para>
+
+         <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+session.delete(p);
+session.flush();]]></programlisting>
+     
+         <para>
+             Sin embargo, este c&#x00f3;digo
+         </para>
+
+         <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+c.setParent(null);
+session.flush();]]></programlisting>
+     
+         <para>
+             no quitar&#x00e1; <literal>c</literal> de la base de datos; s&#x00f3;lo quitar&#x00e1; el enlace a <literal>p</literal>
+             (y causar&#x00e1; una violaci&#x00f3;n a una restricci&#x00f3;n <literal>NOT NULL</literal>). Necesitas borrar el hijo
+             expl&#x00ed;citamente llamando a <literal>delete()</literal>.
+         </para>
+
+         <programlisting><![CDATA[Parent p = (Parent) session.load(Parent.class, pid);
+Child c = (Child) p.getChildren().iterator().next();
+p.getChildren().remove(c);
+session.delete(c);
+session.flush();]]></programlisting>
+
+         <para>
+             Ahora, en nuestro caso, un <literal>Child</literal> no puede existir realmente sin su padre. De modo que
+             si quitamos un <literal>Child</literal> de la colecci&#x00f3;n, realmente queremos que sea borrado. Para esto,
+             debemos usar <literal>cascade="all-delete-orphan"</literal>.
+         </para>
+
+        <programlisting><![CDATA[<set name="children" inverse="true" cascade="all-delete-orphan">
+    <key column="parent_id"/>
+    <one-to-many class="Child"/>
+</set>]]></programlisting>
+
+         <para>
+             Nota: aunque el mapeo de la colecci&#x00f3;n especifique <literal>inverse="true"</literal>, el tratamiento en
+             cascada se procesa a&#x00fa;n al iterar los elementos de colecci&#x00f3;n. De modo que si requieres que un objeto sea
+             salvado, borrado o actualizado en cascada, debes a&#x00f1;adirlo a la colecci&#x00f3;n. No es suficiente con simplemente
+             llamar a <literal>setParent()</literal>.
+         </para>
+               
+     </sect1>
+     
+     <sect1 id="example-parentchild-update">
+         <title>Tratamiento en cascada y <literal>unsaved-value</literal></title>
+     
+         <para>
+             Sup&#x00f3;n que hemos cargado un <literal>Parent</literal> en una <literal>Session</literal>, hemos hecho algunos
+             cambios en una acci&#x00f3;n de UI y deseamos hacer persistentes estos cambios en una nueva sesi&#x00f3;n llamando a
+             <literal>update()</literal>. El <literal>Parent</literal> contendr&#x00e1; una colecci&#x00f3;n de hijos y, ya que
+             est&#x00e1; habilitado el tratamiento en cascada, Hibernate necesita saber qu&#x00e9; hijos est&#x00e1;n reci&#x00e9;n instanciados
+             y cu&#x00e1;les representan filas existentes en la base de datos. Asumamos que tanto <literal>Parent</literal> como
+             <literal>Child</literal> tienen propiedades identificadoras generadas de tipo <literal>Long</literal>.
+             Hibernate usar&#x00e1; el identificador y el valor de la propiedad de versi&#x00f3;n/timestamp para determinar cu&#x00e1;les de
+             los hijos son nuevos. (Ver <xref linkend="objectstate-saveorupdate"/>.) <emphasis>En Hibernate3, no es
+             m&#x00e1;s necesario especificar un <literal>unsaved-value</literal> expl&#x00ed;citamente.</emphasis>
+         </para>
+
+         <para>
+             The following code will update <literal>parent</literal> and <literal>child</literal> and insert 
+             <literal>newChild</literal>.
+         </para>
+
+         <programlisting><![CDATA[//parent and child were both loaded in a previous session
+parent.addChild(child);
+Child newChild = new Child();
+parent.addChild(newChild);
+session.update(parent);
+session.flush();]]></programlisting>
+     
+         <para>
+             Bueno, todo eso est&#x00e1; muy bien para el caso de un identificador generado, pero &#x00bf;qu&#x00e9; de los
+             identificadores asignados y de los identificadores compuestos? Esto es m&#x00e1;s dif&#x00ed;cil, ya que Hibernate
+             no puede usar la propiedad identificadora para distinguir entre un objeto reci&#x00e9;n instanciado (con un
+             identificador asignado por el usuario) y un objeto cargado en una sesi&#x00f3;n previa. En este caso, Hibernate
+             bien usar&#x00e1; la propiedad de versi&#x00f3;n o timestamp, o bien consultar&#x00e1; realmente el cach&#x00e9; de segundo nivel,
+             o bien, en el peor de los casos, la base de datos, para ver si existe la fila.
+         </para>
+         
+         <!-- undocumenting
+         <para>
+             There is one further possibility. The <literal>Interceptor</literal> method named 
+             <literal>isUnsaved()</literal> lets the application implement its own strategy for distinguishing
+             newly instantiated objects. For example, you could define a base class for your persistent classes.
+         </para>
+
+         <programlisting><![CDATA[public class Persistent {
+    private boolean _saved = false;
+    public void onSave() {
+        _saved=true;
+    }
+    public void onLoad() {
+        _saved=true;
+    }
+    ......
+    public boolean isSaved() {
+        return _saved;
+    }
+}]]></programlisting>
+     
+         <para>
+             (The <literal>saved</literal> property is non-persistent.)
+             Now implement <literal>isUnsaved()</literal>, along with <literal>onLoad()</literal>
+             and <literal>onSave()</literal> as follows.
+         </para>
+
+         <programlisting><![CDATA[public Boolean isUnsaved(Object entity) {
+    if (entity instanceof Persistent) {
+        return new Boolean( !( (Persistent) entity ).isSaved() );
+    }
+    else {
+        return null;
+    }
+}
+
+public boolean onLoad(Object entity, 
+    Serializable id,
+    Object[] state,
+    String[] propertyNames,
+    Type[] types) {
+
+    if (entity instanceof Persistent) ( (Persistent) entity ).onLoad();
+    return false;
+}
+
+public boolean onSave(Object entity,
+    Serializable id,
+    Object[] state,
+    String[] propertyNames,
+    Type[] types) {
+        
+    if (entity instanceof Persistent) ( (Persistent) entity ).onSave();
+    return false;
+}]]></programlisting>
+
+		<para>
+			Don't worry; in Hibernate3 you don't need to write any of this kind of code if you don't want to.
+		</para>
+     -->
+     </sect1>
+
+     <sect1 id="example-parentchild-conclusion">
+         <title>Conclusi&#x00f3;n</title>
+
+         <para>
+             Hay que resumir un poco aqu&#x00ed; y podr&#x00ed;a parecer confuso a la primera vez. Sin embargo, en la pr&#x00e1;ctica,
+             todo funciona muy agradablemente. La mayor&#x00ed;a de las aplicaciones de Hibernate usan el patr&#x00f3;n
+             padre / hijo en muchos sitios.
+         </para>
+
+         <para>
+             Hemos mencionado una alternativa en el primer p&#x00e1;rrafo. Ninguno de los temas anteriores existe en el caso
+             de los mapeos <literal>&lt;composite-element&gt;</literal>, que tienen exactamente la sem&#x00e1;ntica de una
+             relaci&#x00f3;n padre / hijo. Desafortunadamente, hay dos grandes limitaciones para las clases de elementos
+             compuestos: los elementos compuestos no pueden poseer sus propias colecciones, y no deben ser el hijo
+             de cualquier otra entidad que no sea su padre &#x00fa;nico.
+         </para>
+     
+     </sect1>
+     
+</chapter>
\ No newline at end of file

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_weblog.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/example_weblog.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_weblog.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/example_weblog.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,429 @@
+<chapter id="example-weblog">
+    <title>Ejemplo: Aplicaci&#x00f3;n de Weblog</title>
+
+    <sect1 id="example-weblog-classes">
+        <title>Clases Persistentes</title>
+
+        <para>
+            Las clases persistentes representan un weblog, y un &#x00ed;tem enviado a un weblog. Van a ser modelados como una
+            relaci&#x00f3;n padre/hijo est&#x00f1;ndar, pero usaremos un bag ordenado, en vez de un conjunto (set).
+        </para>
+
+        <programlisting><![CDATA[package eg;
+
+import java.util.List;
+
+public class Blog {
+    private Long _id;
+    private String _name;
+    private List _items;
+
+    public Long getId() {
+        return _id;
+    }
+    public List getItems() {
+        return _items;
+    }
+    public String getName() {
+        return _name;
+    }
+    public void setId(Long long1) {
+        _id = long1;
+    }
+    public void setItems(List list) {
+        _items = list;
+    }
+    public void setName(String string) {
+        _name = string;
+    }
+}]]></programlisting>
+
+        <programlisting><![CDATA[package eg;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+public class BlogItem {
+    private Long _id;
+    private Calendar _datetime;
+    private String _text;
+    private String _title;
+    private Blog _blog;
+
+    public Blog getBlog() {
+        return _blog;
+    }
+    public Calendar getDatetime() {
+        return _datetime;
+    }
+    public Long getId() {
+        return _id;
+    }
+    public String getText() {
+        return _text;
+    }
+    public String getTitle() {
+        return _title;
+    }
+    public void setBlog(Blog blog) {
+        _blog = blog;
+    }
+    public void setDatetime(Calendar calendar) {
+        _datetime = calendar;
+    }
+    public void setId(Long long1) {
+        _id = long1;
+    }
+    public void setText(String string) {
+        _text = string;
+    }
+    public void setTitle(String string) {
+        _title = string;
+    }
+}]]></programlisting>
+
+    </sect1>
+
+    <sect1 id="example-weblog-mappings">
+        <title>Mapeos de Hibernate</title>
+
+        <para>
+            Los mapeos XML ahora deben ser absolutamente directos.
+        </para>
+        
+        <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+    <class
+        name="Blog"
+        table="BLOGS">
+
+        <id
+            name="id"
+            column="BLOG_ID">
+
+            <generator class="native"/>
+
+        </id>
+
+        <property
+            name="name"
+            column="NAME"
+            not-null="true"
+            unique="true"/>
+
+        <bag
+            name="items"
+            inverse="true"
+            order-by="DATE_TIME"
+            cascade="all">
+
+            <key column="BLOG_ID"/>
+            <one-to-many class="BlogItem"/>
+
+        </bag>
+
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+        <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="eg">
+
+    <class
+        name="BlogItem"
+        table="BLOG_ITEMS"
+        dynamic-update="true">
+
+        <id
+            name="id"
+            column="BLOG_ITEM_ID">
+
+            <generator class="native"/>
+
+        </id>
+
+        <property
+            name="title"
+            column="TITLE"
+            not-null="true"/>
+
+        <property
+            name="text"
+            column="TEXT"
+            not-null="true"/>
+
+        <property
+            name="datetime"
+            column="DATE_TIME"
+            not-null="true"/>
+
+        <many-to-one
+            name="blog"
+            column="BLOG_ID"
+            not-null="true"/>
+
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+    </sect1>
+    
+    <sect1 id="example-weblog-code">
+        <title>C&#x00f3;digo Hibernate</title>
+
+        <para>
+            La siguiente clase demuestra algunos de los tipos de cosas que podemos haces con estas clases,
+            usando Hibernate.
+        </para>
+
+        <programlisting><![CDATA[package eg;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+
+public class BlogMain {
+    
+    private SessionFactory _sessions;
+    
+    public void configure() throws HibernateException {
+        _sessions = new Configuration()
+            .addClass(Blog.class)
+            .addClass(BlogItem.class)
+            .buildSessionFactory();
+    }
+    
+    public void exportTables() throws HibernateException {
+        Configuration cfg = new Configuration()
+            .addClass(Blog.class)
+            .addClass(BlogItem.class);
+        new SchemaExport(cfg).create(true, true);
+    }
+    
+    public Blog createBlog(String name) throws HibernateException {
+        
+        Blog blog = new Blog();
+        blog.setName(name);
+        blog.setItems( new ArrayList() );
+        
+        Session session = _sessions.openSession();
+        Transaction tx = null;
+        try {
+            tx = session.beginTransaction();
+            session.persist(blog);
+            tx.commit();
+        }
+        catch (HibernateException he) {
+            if (tx!=null) tx.rollback();
+            throw he;
+        }
+        finally {
+            session.close();
+        }
+        return blog;
+    }
+    
+    public BlogItem createBlogItem(Blog blog, String title, String text)
+                        throws HibernateException {
+        
+        BlogItem item = new BlogItem();
+        item.setTitle(title);
+        item.setText(text);
+        item.setBlog(blog);
+        item.setDatetime( Calendar.getInstance() );
+        blog.getItems().add(item);
+        
+        Session session = _sessions.openSession();
+        Transaction tx = null;
+        try {
+            tx = session.beginTransaction();
+            session.update(blog);
+            tx.commit();
+        }
+        catch (HibernateException he) {
+            if (tx!=null) tx.rollback();
+            throw he;
+        }
+        finally {
+            session.close();
+        }
+        return item;
+    }
+    
+    public BlogItem createBlogItem(Long blogid, String title, String text)
+                        throws HibernateException {
+        
+        BlogItem item = new BlogItem();
+        item.setTitle(title);
+        item.setText(text);
+        item.setDatetime( Calendar.getInstance() );
+        
+        Session session = _sessions.openSession();
+        Transaction tx = null;
+        try {
+            tx = session.beginTransaction();
+            Blog blog = (Blog) session.load(Blog.class, blogid);
+            item.setBlog(blog);
+            blog.getItems().add(item);
+            tx.commit();
+        }
+        catch (HibernateException he) {
+            if (tx!=null) tx.rollback();
+            throw he;
+        }
+        finally {
+            session.close();
+        }
+        return item;
+    }
+    
+    public void updateBlogItem(BlogItem item, String text)
+                    throws HibernateException {
+        
+        item.setText(text);
+        
+        Session session = _sessions.openSession();
+        Transaction tx = null;
+        try {
+            tx = session.beginTransaction();
+            session.update(item);
+            tx.commit();
+        }
+        catch (HibernateException he) {
+            if (tx!=null) tx.rollback();
+            throw he;
+        }
+        finally {
+            session.close();
+        }
+    }
+    
+    public void updateBlogItem(Long itemid, String text)
+                    throws HibernateException {
+    
+        Session session = _sessions.openSession();
+        Transaction tx = null;
+        try {
+            tx = session.beginTransaction();
+            BlogItem item = (BlogItem) session.load(BlogItem.class, itemid);
+            item.setText(text);
+            tx.commit();
+        }
+        catch (HibernateException he) {
+            if (tx!=null) tx.rollback();
+            throw he;
+        }
+        finally {
+            session.close();
+        }
+    }
+    
+    public List listAllBlogNamesAndItemCounts(int max)
+                    throws HibernateException {
+        
+        Session session = _sessions.openSession();
+        Transaction tx = null;
+        List result = null;
+        try {
+            tx = session.beginTransaction();
+            Query q = session.createQuery(
+                "select blog.id, blog.name, count(blogItem) " +
+                "from Blog as blog " +
+                "left outer join blog.items as blogItem " +
+                "group by blog.name, blog.id " +
+                "order by max(blogItem.datetime)"
+            );
+            q.setMaxResults(max);
+            result = q.list();
+            tx.commit();
+        }
+        catch (HibernateException he) {
+            if (tx!=null) tx.rollback();
+            throw he;
+        }
+        finally {
+            session.close();
+        }
+        return result;
+    }
+    
+    public Blog getBlogAndAllItems(Long blogid)
+                    throws HibernateException {
+        
+        Session session = _sessions.openSession();
+        Transaction tx = null;
+        Blog blog = null;
+        try {
+            tx = session.beginTransaction();
+            Query q = session.createQuery(
+                "from Blog as blog " +
+                "left outer join fetch blog.items " +
+                "where blog.id = :blogid"
+            );
+            q.setParameter("blogid", blogid);
+            blog  = (Blog) q.uniqueResult();
+            tx.commit();
+        }
+        catch (HibernateException he) {
+            if (tx!=null) tx.rollback();
+            throw he;
+        }
+        finally {
+            session.close();
+        }
+        return blog;
+    }
+    
+    public List listBlogsAndRecentItems() throws HibernateException {
+        
+        Session session = _sessions.openSession();
+        Transaction tx = null;
+        List result = null;
+        try {
+            tx = session.beginTransaction();
+            Query q = session.createQuery(
+                "from Blog as blog " +
+                "inner join blog.items as blogItem " +
+                "where blogItem.datetime > :minDate"
+            );
+
+            Calendar cal = Calendar.getInstance();
+            cal.roll(Calendar.MONTH, false);
+            q.setCalendar("minDate", cal);
+            
+            result = q.list();
+            tx.commit();
+        }
+        catch (HibernateException he) {
+            if (tx!=null) tx.rollback();
+            throw he;
+        }
+        finally {
+            session.close();
+        }
+        return result;
+    }
+}]]></programlisting>
+
+    </sect1>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/filters.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/filters.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/filters.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/filters.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,130 @@
+<chapter id="filters">
+    <title>Filtrando datos</title>
+    
+    <para>
+        Hibernate3 provee un nuevo enfoque innovador para manejar datos con reglas de "visibilidad".
+        Un <emphasis>filtro de Hibernate</emphasis> es un filtro global, con nombre y parametrizado
+        que puede ser habilitado o deshabilitado para una sesión de Hibernate en particular.
+    </para>
+
+    <sect1 id="objectstate-filters">
+        <title>Filtros de Hibernate</title>
+
+        <para>
+            Hibernate3 añade la habilidad de predefinir criterios de filtros y unir esos filtros tanto a
+            nivel de una clase como de una colección. Un criterio de filtro es la habilidad de definir una
+            cláusula de restricción muy similar al atributo existente "where" disponible en el elemento
+            class y varios elementos de colección. Excepto en que estos filtros pueden ser parametrizados.
+            La aplicación puede tomar la decisión en tiempo de ejecución de qué filtros deben estar
+            habilitados y cuáles deben ser sus parámetros. Los filtros pueden ser usados como vistas de
+            base de datos, pero parametrizados dentro de la aplicación.
+        </para>
+
+        <para>
+            Para usar los filtros, éstos deben primero ser definidos y luego unidos a los elementos de mapeo
+            apropiados. Para definir un filtro, usa el elemento <literal>&lt;filter-def/&gt;</literal> dentro
+            de un elemento <literal>&lt;hibernate-mapping/&gt;</literal>:
+        </para>
+
+        <programlisting><![CDATA[<filter-def name="myFilter">
+    <filter-param name="myFilterParam" type="string"/>
+</filter-def>]]></programlisting>
+
+        <para>
+            Entonces este filtro puede ser unido a una clase:
+        </para>
+
+        <programlisting><![CDATA[<class name="myClass" ...>
+    ...
+    <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</class>]]></programlisting>
+
+        <para>
+            o a una colección:
+        </para>
+
+        <programlisting><![CDATA[<set ...>
+    <filter name="myFilter" condition=":myFilterParam = MY_FILTERED_COLUMN"/>
+</set>]]></programlisting>
+
+        <para>
+            o incluso a ambos (o muchos de cada uno) al mismo tiempo.
+        </para>
+
+        <para>
+            Los métodos en <literal>Session</literal> son: <literal>enableFilter(String filterName)</literal>,
+            <literal>getEnabledFilter(String filterName)</literal>, y <literal>disableFilter(String filterName)</literal>.
+            Por defecto, los filtros <emphasis>no</emphasis> están habilitados para una sesión dada; deben ser
+            habilitados explícitamente por medio del uso del método <literal>Session.enableFilter()</literal>,
+            que devuelve una instancia de la interface <literal>Filter</literal>. Usando el filtro simple definido
+            arriba, esto se vería así:
+        </para>
+
+        <programlisting><![CDATA[session.enableFilter("myFilter").setParameter("myFilterParam", "some-value");]]></programlisting>
+
+        <para>
+            Nota que los métodos en la interface org.hibernate.Filter permiten el encadenamiento de métodos
+            común en gran parte de Hibernate.
+        </para>
+
+        <para>
+            Un ejemplo completo, usando datos temporales con un patrón efectivo de fechas de registro:
+        </para>
+
+        <programlisting><![CDATA[<filter-def name="effectiveDate">
+    <filter-param name="asOfDate" type="date"/>
+</filter-def>
+
+<class name="Employee" ...>
+...
+    <many-to-one name="department" column="dept_id" class="Department"/>
+    <property name="effectiveStartDate" type="date" column="eff_start_dt"/>
+    <property name="effectiveEndDate" type="date" column="eff_end_dt"/>
+...
+    <!--
+        Note that this assumes non-terminal records have an eff_end_dt set to
+        a max db date for simplicity-sake
+    -->
+    <filter name="effectiveDate"
+            condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+</class>
+
+<class name="Department" ...>
+...
+    <set name="employees" lazy="true">
+        <key column="dept_id"/>
+        <one-to-many class="Employee"/>
+        <filter name="effectiveDate"
+                condition=":asOfDate BETWEEN eff_start_dt and eff_end_dt"/>
+    </set>
+</class>]]></programlisting>
+
+        <para>
+            Entonces, en orden de asegurar que siempre tendrás de vuelta registros actualmente efectivos,
+            simplemente habilita el filtro en la sesión previo a recuperar los datos de empleados:
+        </para>
+
+<programlisting><![CDATA[Session session = ...;
+session.enabledFilter("effectiveDate").setParameter("asOfDate", new Date());
+List results = session.createQuery("from Employee as e where e.salary > :targetSalary")
+         .setLong("targetSalary", new Long(1000000))
+         .list();
+]]></programlisting>
+
+        <para>
+            En el HQL de arriba, aunque sólo hemos mencionado explícitamente una restricción de salario en
+            los resultados, debido al filtro habilitado la consulta sólo devolverá empleados actualmente activos
+            que tengan un salario mayor que un millón de dólares.
+        </para>
+
+        <para>
+            Nota: si planeas usar filtros con unión externa (outer joining) (bien a través de HQL, o bien
+            de recuperación de carga) sé cuidadoso en la dirección de expresión de la condición. Lo más seguro
+            es establecer esto para unión externa izquierda (left outer joining). En general, coloca el primer
+            parámetro seguido del nombre(s) de columna(s) después del operador.
+        </para>
+
+    </sect1>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/inheritance_mapping.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/inheritance_mapping.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/inheritance_mapping.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/inheritance_mapping.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,464 @@
+<chapter id="inheritance">
+    <title>Mapeo de Herencia</title>
+
+    <sect1 id="inheritance-strategies" revision="2">
+        <title>Las Tres Estrategias</title>
+
+        <para>
+            Hibernate soporta las tres estrategias b&#x00e1;sicas de mapeo de herencia:
+        </para>
+
+        <itemizedlist>
+        <listitem>
+        <para>
+            tabla por jerarqu&#x00ed;a de clases
+        </para>
+        </listitem>
+        <listitem>
+        <para>
+            tabla por subclase
+        </para>
+        </listitem>
+        <listitem>
+        <para>
+            tabla por clase concreta
+        </para>
+        </listitem>
+        </itemizedlist>
+        
+        <para>
+            En adici&#x00f3;n, Hibernate soporta un cuarto, ligeramente diferente tipo
+            de polimorfismo:
+        </para>
+
+        <itemizedlist>
+        <listitem>
+        <para>
+            polimorfismo impl&#x00ed;cito
+        </para>
+        </listitem>
+        </itemizedlist>
+        
+        <para>
+            Es posible usar estrategias de mapeo diferentes para diferentes
+            ramificaciones de la misma jerarqu&#x00ed;a de herencia, y entonces usar
+            polimorfismo impl&#x00ed;cito para conseguir polimorfismo a trav&#x00e9;s de
+            toda la jerarqu&#x00ed;a. Sin embargo, Hibernate no soporta la mezcla de
+            mapeos <literal>&lt;subclass&gt;</literal>,
+            y <literal>&lt;joined-subclass&gt;</literal>
+            y <literal>&lt;union-subclass&gt;</literal> bajo el mismo elemento
+            <literal>&lt;class&gt;</literal> ra&#x00ed;z. Es posible mezclar juntas las
+            estrategias de tabla por jerarqu&#x00ed;a y tabla por subclase, bajo el mismo
+            elemento <literal>&lt;class&gt;</literal>, combinando los elementos
+            <literal>&lt;subclass&gt;</literal> y <literal>&lt;join&gt;</literal>
+            (ver debajo).
+        </para>
+        
+        <sect2 id="inheritance-tableperclass" >
+        <title>Tabla por jerarqu&#x00ed;a de clases</title>
+
+        <para>
+            Sup&#x00f3;n que tenemos una interface <literal>Payment</literal>, con
+            los implementadores <literal>CreditCardPayment</literal>,
+            <literal>CashPayment</literal>, <literal>ChequePayment</literal>.
+            El mapeo de tabla por jerarqu&#x00ed;a se ver&#x00ed;a as&#x00ed;:
+        </para>
+
+        <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+    <id name="id" type="long" column="PAYMENT_ID">
+        <generator class="native"/>
+    </id>
+    <discriminator column="PAYMENT_TYPE" type="string"/>
+    <property name="amount" column="AMOUNT"/>
+    ...
+    <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+        <property name="creditCardType" column="CCTYPE"/>
+        ...
+    </subclass>
+    <subclass name="CashPayment" discriminator-value="CASH">
+        ...
+    </subclass>
+    <subclass name="ChequePayment" discriminator-value="CHEQUE">
+        ...
+    </subclass>
+</class>]]></programlisting>
+
+        <para>
+            Se requiere exactamente una tabla. Hay una gran limitaci&#x00f3;n de esta estrategia de mapeo:
+            las columnas declaradas por las subclases, como <literal>CCTYPE</literal>, no pueden
+            tener restricciones <literal>NOT NULL</literal>.
+        </para>
+        
+        </sect2>
+
+        <sect2 id="inheritance-tablepersubclass">
+        <title>Tabla por subclase</title>
+
+        <para>
+            Un mapeo de tabla por sublclase se ver&#x00ed;a as&#x00ed;:
+        </para>
+
+        <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+    <id name="id" type="long" column="PAYMENT_ID">
+        <generator class="native"/>
+    </id>
+    <property name="amount" column="AMOUNT"/>
+    ...
+    <joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+        <key column="PAYMENT_ID"/>
+        <property name="creditCardType" column="CCTYPE"/>
+        ...
+    </joined-subclass>
+    <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+        <key column="PAYMENT_ID"/>
+        ...
+    </joined-subclass>
+    <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+        <key column="PAYMENT_ID"/>
+        ...
+    </joined-subclass>
+</class>]]></programlisting>
+
+        <para>
+            Se requieren cuatro tablas. Las tres tablas de subclase tienen
+            asociaciones de clave primaria a la tabla de superclase (de modo
+            que en el modelo relacional es realmente una asociaci&#x00f3;n uno-a-uno).
+        </para>
+
+        </sect2>
+
+        <sect2 id="inheritance-tablepersubclass-discriminator" revision="2">
+        <title>Tabla por subclase, usando un discriminador</title>
+
+        <para>
+            Observa que la implementaci&#x00f3;n de Hibernate de tabla por subclase
+            no requiere ninguna columna discriminadora. Otros mapeadores
+            objeto/relacional usan una implementaci&#x00f3;n diferente de tabla por
+            subclase que requiere una columna discriminadora de tipo en la tabla
+            de superclase. Este enfoque es mucho m&#x00e1;s dif&#x00ed;cil de implementar
+            pero discutiblemente m&#x00e1;s correcto desde un punto de vista relacional.
+            Si quisieras usar una columna discriminadora con la estrategia de
+            tabla por subclase, puedes combinar el uso de <literal>&lt;subclass&gt;</literal>
+            y <literal>&lt;join&gt;</literal>, como sigue:
+        </para>
+
+        <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+    <id name="id" type="long" column="PAYMENT_ID">
+        <generator class="native"/>
+    </id>
+    <discriminator column="PAYMENT_TYPE" type="string"/>
+    <property name="amount" column="AMOUNT"/>
+    ...
+    <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+        <join table="CREDIT_PAYMENT">
+            <key column="PAYMENT_ID"/>
+            <property name="creditCardType" column="CCTYPE"/>
+            ...
+        </join>
+    </subclass>
+    <subclass name="CashPayment" discriminator-value="CASH">
+        <join table="CASH_PAYMENT">
+            <key column="PAYMENT_ID"/>
+            ...
+        </join>
+    </subclass>
+    <subclass name="ChequePayment" discriminator-value="CHEQUE">
+        <join table="CHEQUE_PAYMENT" fetch="select">
+            <key column="PAYMENT_ID"/>
+            ...
+        </join>
+    </subclass>
+</class>]]></programlisting>
+
+        <para>
+            la declaraci&#x00f3;n opcional <literal>fetch="select"</literal> dice a Hibernate
+            que no recupere los datos de la subclase <literal>ChequePayment</literal>
+            usando una uni&#x00f3;n externa (outer join) al consultar la superclase.
+        </para>
+
+        </sect2>
+
+        <sect2 id="inheritance-mixing-tableperclass-tablepersubclass">
+        <title>Mezclando tabla por jerarqu&#x00ed;a de clases con tabla por subclase</title>
+
+        <para>
+            Puedes incluso mezclar las estrategias de tabla po jerarqu&#x00ed;a y tabla por
+            subclase usando este enfoque:
+        </para>
+
+        <programlisting><![CDATA[<class name="Payment" table="PAYMENT">
+    <id name="id" type="long" column="PAYMENT_ID">
+        <generator class="native"/>
+    </id>
+    <discriminator column="PAYMENT_TYPE" type="string"/>
+    <property name="amount" column="AMOUNT"/>
+    ...
+    <subclass name="CreditCardPayment" discriminator-value="CREDIT">
+        <join table="CREDIT_PAYMENT">
+            <property name="creditCardType" column="CCTYPE"/>
+            ...
+        </join>
+    </subclass>
+    <subclass name="CashPayment" discriminator-value="CASH">
+        ...
+    </subclass>
+    <subclass name="ChequePayment" discriminator-value="CHEQUE">
+        ...
+    </subclass>
+</class>]]></programlisting>
+
+        <para>
+            Para cualquiera de estas estrategias de mapeo, una asociaci&#x00f3;n polim&#x00f3;rfica
+            a la clase ra&#x00ed;z <literal>Payment</literal> es mapeada usando <literal>&lt;many-to-one&gt;</literal>.
+        </para>
+
+        <programlisting><![CDATA[<many-to-one name="payment" column="PAYMENT_ID" class="Payment"/>]]></programlisting>
+    
+        </sect2>
+
+        <sect2 id="inheritance-tableperconcrete" revision="1">
+        <title>Tabla por clase concreta</title>
+
+        <para>
+            Podr&#x00ed;amos ir de dos maneras a la estrategia de mapeo de tabla por clase
+            concreta. La primera es usar <literal>&lt;union-subclass&gt;</literal>.
+        </para>
+
+        <programlisting><![CDATA[<class name="Payment">
+    <id name="id" type="long" column="PAYMENT_ID">
+        <generator class="sequence"/>
+    </id>
+    <property name="amount" column="AMOUNT"/>
+    ...
+    <union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
+        <property name="creditCardType" column="CCTYPE"/>
+        ...
+    </union-subclass>
+    <union-subclass name="CashPayment" table="CASH_PAYMENT">
+        ...
+    </union-subclass>
+    <union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+        ...
+    </union-subclass>
+</class>]]></programlisting>
+
+        <para>
+            Est&#x00e1;n implicadas tres tablas. Cada tabla define columnas para todas las
+            propiedades de la clase, inccluyendo las propiedades heredadas.
+        </para>
+        
+        <para>
+            La limitaci&#x00f3;n de este enfoque es que si una propiedad es mapeada en la
+            superclase, el nombre de columna debe ser el mismo en todas las tablas
+            de subclase. (Podr&#x00ed;amos relajar esto en un lanzamiento futuro de Hibernate.)
+            La estrategia de generador de indentidad no est&#x00e1; permitida en la herencia
+            de uni&#x00f3;n de subclase, de hecho la semilla de clave primaria tiene que ser
+            compartida a trav&#x00e9;s de todas las subclases unidas de una jerarqu&#x00ed;a.
+        </para>
+        
+        </sect2>
+
+        <sect2 id="inheritance-tableperconcreate-polymorphism">
+        <title>Tabla por clase concreta, usando polimorfismo impl&#x00ed;cito</title>
+
+        <para>
+            Un enfoque alternativo es hacer uso de polimorfismo impl&#x00ed;cito:
+        </para>
+
+        <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+    <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+        <generator class="native"/>
+    </id>
+    <property name="amount" column="CREDIT_AMOUNT"/>
+    ...
+</class>
+
+<class name="CashPayment" table="CASH_PAYMENT">
+    <id name="id" type="long" column="CASH_PAYMENT_ID">
+        <generator class="native"/>
+    </id>
+    <property name="amount" column="CASH_AMOUNT"/>
+    ...
+</class>
+
+<class name="ChequePayment" table="CHEQUE_PAYMENT">
+    <id name="id" type="long" column="CHEQUE_PAYMENT_ID">
+        <generator class="native"/>
+    </id>
+    <property name="amount" column="CHEQUE_AMOUNT"/>
+    ...
+</class>]]></programlisting>
+           
+        <para>
+            Nota que en ning&#x00fa;n sitio mencionamos la interface <literal>Payment</literal>
+            expl&#x00ed;citamente. Nota adem&#x00e1;s que las propiedades de <literal>Payment</literal>
+            son mapeadas en cada una de las subclases. Si quieres evitar duplicaci&#x00f3;n,
+            considera usar entidades XML. (por ejemplo,
+            <literal>[ &lt;!ENTITY allproperties SYSTEM "allproperties.xml"&gt; ]</literal>
+            en la declaraci&#x00f3;n <literal>DOCTYPE</literal> y <literal>&amp;allproperties;</literal>
+            en el mapeo).
+        </para>
+        
+        <para>
+            La desventaja de este enfoque es que Hibernate no genera <literal>UNION</literal>s
+            de SQL al realizar consultas polim&#x00f3;rficas.
+        </para>
+
+        <para>
+            Para esta estrategia de mapeo, una asociaci&#x00f3;n polim&#x00f3;rfica a <literal>Payment</literal>
+            es mapeada generalmente usando <literal>&lt;any&gt;</literal>.
+        </para>
+
+        <programlisting><![CDATA[<any name="payment" meta-type="string" id-type="long">
+    <meta-value value="CREDIT" class="CreditCardPayment"/>
+    <meta-value value="CASH" class="CashPayment"/>
+    <meta-value value="CHEQUE" class="ChequePayment"/>
+    <column name="PAYMENT_CLASS"/>
+    <column name="PAYMENT_ID"/>
+</any>]]></programlisting>
+           
+        </sect2>
+
+        <sect2 id="inheritace-mixingpolymorphism">
+        <title>Mezclando polimorfismo impl&#x00ed;cito con otros mapeos de herencia</title>
+
+        <para>
+            Hay una cosa m&#x00e1;s por notar acerca de este mapeo. Ya que las subclases se mapean
+            cada una en su propio elemento <literal>&lt;class&gt;</literal> (y ya que
+            <literal>Payment</literal> es s&#x00f3;lo una interface), cada una de las subclases
+            podr&#x00ed;a ser parte de otra jerarqu&#x00ed;a de herencia! (Y todav&#x00ed;a puedes seguir usando
+            consultas polim&#x00f3;rficas contra la interface <literal>Payment</literal>.)
+       </para>
+
+        <programlisting><![CDATA[<class name="CreditCardPayment" table="CREDIT_PAYMENT">
+    <id name="id" type="long" column="CREDIT_PAYMENT_ID">
+        <generator class="native"/>
+    </id>
+    <discriminator column="CREDIT_CARD" type="string"/>
+    <property name="amount" column="CREDIT_AMOUNT"/>
+    ...
+    <subclass name="MasterCardPayment" discriminator-value="MDC"/>
+    <subclass name="VisaPayment" discriminator-value="VISA"/>
+</class>
+
+<class name="NonelectronicTransaction" table="NONELECTRONIC_TXN">
+    <id name="id" type="long" column="TXN_ID">
+        <generator class="native"/>
+    </id>
+    ...
+    <joined-subclass name="CashPayment" table="CASH_PAYMENT">
+        <key column="PAYMENT_ID"/>
+        <property name="amount" column="CASH_AMOUNT"/>
+        ...
+    </joined-subclass>
+    <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
+        <key column="PAYMENT_ID"/>
+        <property name="amount" column="CHEQUE_AMOUNT"/>
+        ...
+    </joined-subclass>
+</class>]]></programlisting>
+
+        <para>
+            Una vez m&#x00e1;s, no mencionamos a <literal>Payment</literal> expl&#x00ed;citamente.
+            Si ejecutamos una consulta contra la interface <literal>Payment</literal>
+            - por ejemplo, <literal>from Payment</literal> - Hibernate devuelve
+            autom&#x00e1;ticamente instancias de <literal>CreditCardPayment</literal>
+            (y sus subclases, ya que ellas tambi&#x00e9;n implementan <literal>Payment</literal>),
+            <literal>CashPayment</literal> y <literal>ChequePayment</literal> pero
+            no instancias de <literal>NonelectronicTransaction</literal>.
+        </para>
+        
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="inheritance-limitations">
+        <title>Limitaciones</title>
+
+        <para>
+            Existen ciertas limitaciones al enfoque de "polimorfismo impl&#x00ed;cito" en
+            la estrategia de mapeo de tabla por clase concreta. Existen limitaciones
+            algo menos restrictivas a los mapeos <literal>&lt;union-subclass&gt;</literal>.
+        </para>
+
+        <para>
+            La siguiente tabla muestra las limitaciones de mapeos de tabla por
+            clase concreta, y de polmorfismo impl&#x00ed;cito, en Hibernate.
+        </para>
+            
+        <table frame="topbot">
+            <title>Funcionalidades de mapeo de herencia</title>
+            <tgroup cols='8' align='left' colsep='1' rowsep='1'>
+            <colspec colname='c1' colwidth="1*"/>
+            <colspec colname='c2' colwidth="1*"/>
+            <colspec colname='c3' colwidth="1*"/>
+            <colspec colname='c4' colwidth="1*"/>
+            <colspec colname='c5' colwidth="1*"/>
+            <colspec colname='c6' colwidth="1*"/>
+            <colspec colname='c7' colwidth="1*"/>
+            <colspec colname='c8' colwidth="1*"/>
+            <thead>
+            <row>
+              <entry>Estrategia de herencia</entry>
+              <entry>muchos-a-uno polim&#x00f3;rfica</entry>
+              <entry>uno-a-uno polim&#x00f3;rfica</entry>
+              <entry>uno-a-muchos polim&#x00f3;rfica</entry>
+              <entry>mushos-a-muchos polim&#x00f3;rfica</entry>
+              <entry><literal>load()/get()</literal> polim&#x00f3;rficos</entry>
+              <entry>Consultas polim&#x00f3;rficas</entry>
+              <entry>Uniones polim&#x00f3;rficas</entry>
+              <entry>Recuperaci&#x00f3;n por uni&#x00f3;n externa (outer join)</entry>
+            </row>
+            </thead>
+            <tbody>
+            <row>
+                <entry>tabla por jerarqu&#x00ed;a de clases</entry>
+                <entry><literal>&lt;many-to-one&gt;</literal></entry>
+                <entry><literal>&lt;one-to-one&gt;</literal></entry>
+                <entry><literal>&lt;one-to-many&gt;</literal></entry>
+                <entry><literal>&lt;many-to-many&gt;</literal></entry>
+                <entry><literal>s.get(Payment.class, id)</literal></entry>
+                <entry><literal>from Payment p</literal></entry>
+                <entry><literal>from Order o join o.payment p</literal></entry>
+                <entry><emphasis>soportada</emphasis></entry>
+            </row>
+            <row>
+                <entry>tabla por subclase</entry>
+                <entry><literal>&lt;many-to-one&gt;</literal></entry>
+                <entry><literal>&lt;one-to-one&gt;</literal></entry>
+                <entry><literal>&lt;one-to-many&gt;</literal></entry>
+                <entry><literal>&lt;many-to-many&gt;</literal></entry>
+                <entry><literal>s.get(Payment.class, id)</literal></entry>
+                <entry><literal>from Payment p</literal></entry>
+                <entry><literal>from Order o join o.payment p</literal></entry>
+                <entry><emphasis>soportada</emphasis></entry>
+            </row>
+            <row>
+                <entry>tabla por clase concreta (union-subclass)</entry>
+                <entry><literal>&lt;many-to-one&gt;</literal></entry>
+                <entry><literal>&lt;one-to-one&gt;</literal></entry>
+                <entry><literal>&lt;one-to-many&gt;</literal> (para <literal>inverse="true"</literal> solamente)</entry>
+                <entry><literal>&lt;many-to-many&gt;</literal></entry>
+                <entry><literal>s.get(Payment.class, id)</literal></entry>
+                <entry><literal>from Payment p</literal></entry>
+                <entry><literal>from Order o join o.payment p</literal></entry>
+                <entry><emphasis>soportada</emphasis></entry>
+            </row>
+            <row>
+                <entry>tabla por clase concreta (polimorfismo impl&#x00ed;cito)</entry>
+                <entry><literal>&lt;any&gt;</literal></entry>
+                <entry><emphasis>no soportada</emphasis></entry>
+                <entry><emphasis>no soportada</emphasis></entry>
+                <entry><literal>&lt;many-to-any&gt;</literal></entry>
+                <entry><literal>s.createCriteria(Payment.class).add( Restrictions.idEq(id) ).uniqueResult()</literal></entry>
+                <entry><literal>from Payment p</literal></entry>
+                <entry><emphasis>no suportadas</emphasis></entry>
+                <entry><emphasis>no soportada</emphasis></entry>
+            </row>
+            </tbody>
+            </tgroup>
+        </table>
+
+    </sect1>
+
+</chapter>

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/performance.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/performance.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/performance.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/performance.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,1334 @@
+<chapter id="performance">
+    <title>Mejorando el rendimiento</title>
+
+    <sect1 id="performance-fetching">
+        <title>Estrategias de recuperaci&#x00f3;n</title>
+
+        <para>
+            Una <emphasis>estrategia de recuperaci&#x00f3;n</emphasis> es la estrategia que usar&#x00e1; Hibernate para recuperar
+            los objetos asociados cuando la aplicaci&#x00f3;n necesite navegar la asociaci&#x00f3;n. Las estrategias de recuperaci&#x00f3;n
+            pueden ser declaradas en los metadatos de mapeo O/R, o sobrescritas por una consulta HQL o
+            <literal>Criteria</literal> en particular.
+        </para>
+
+        <para>
+            Hibernate3 define las siguientes estrategias de recuperaci&#x00f3;n:
+        </para>
+
+        <itemizedlist>
+             <listitem>
+                <para>
+                    <emphasis>Recuperaci&#x00f3;n por uni&#x00f3;n (join fetching)</emphasis> - Hibernate recupera la
+                    instancia asociada o colecci&#x00f3;n en la misma <literal>SELECT</literal>, usando una
+                    <literal>OUTER JOIN</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis>Recuperaci&#x00f3;n por selecci&#x00f3;n (select fetching)</emphasis> - se usa una segunda
+                    <literal>SELECT</literal> para recuperar la entidad asociada o colecci&#x00f3;n. A menos que
+                    deshabilites expl&#x00ed;citamente la recuperaci&#x00f3;n perezosa especificando <literal>lazy="false"</literal>,
+                    la segunda selecci&#x00f3;n s&#x00f3;lo ser&#x00e1; ejecutada cuando realmente accedas a la asociaci&#x00f3;n.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis>Recuperaci&#x00f3;n por subselecci&#x00f3;n (subselect fetching)</emphasis> - se usa una segunda
+                    <literal>SELECT</literal> para recuperar las colecciones asociadas de todas las entidades
+                    recuperadas en una consulta o recuperaci&#x00f3;n previa. A menos que deshabilites expl&#x00ed;citamente la
+                    recuperaci&#x00f3;n perezosa especificando <literal>lazy="false"</literal>, esta segunda selecci&#x00f3;n s&#x00f3;lo
+                    ser&#x00e1; ejecutada cuando realmente accedas a la asociaci&#x00f3;n.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis>Recuperaci&#x00f3;n en lote</emphasis> - una estrategia de optimizaci&#x00f3;n para la recuperaci&#x00f3;n
+                    por selecci&#x00f3;n - Hibernate recupera un lote de instancias de entidad o colecciones en una sola
+                    <literal>SELECT</literal>, especificando una lista de claves primarias o de claves for&#x00e1;neas.
+                </para>
+            </listitem>
+        </itemizedlist>
+        
+        <para>
+            Hibernate tambi&#x00e9;n distingue entre:
+        </para>
+
+        <itemizedlist>
+             <listitem>
+                <para>
+                    <emphasis>Recuperaci&#x00f3;n inmediata</emphasis> - una asociaci&#x00f3;n, colecci&#x00f3;n o atributo es recuperado
+                    inmediatamente, cuando el due&#x00f1;o es cargado.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis>Recuperaci&#x00f3;n perezosa de colecciones</emphasis> - se recupera una colecci&#x00f3;n cuando la
+                    aplicaci&#x00f3;n invoca una operaci&#x00f3;n sobre la colecci&#x00f3;n. (Esto es por defecto para las colecciones.)
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis>Recuperaci&#x00f3;n por proxy</emphasis> - se recupera una asociaci&#x00f3;n monovaluada cuando se
+                    invoca un m&#x00e9;todo que no sea el getter del identificador sobre el objeto asociado.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis>Recuperaci&#x00f3;n perezosa de atributos</emphasis> - se recupera un atributo o una asociaci&#x00f3;n
+                    monovaluada cuando se accede a la variable de instancia (requiere instrumentaci&#x00f3;n del bytecode en
+                    tiempo de ejecuci&#x00f3;n). Este enfoque es raramente necesario.
+                </para>
+            </listitem>
+        </itemizedlist>
+        
+        <para>
+            Aqu&#x00ed; tenemos dos nociones ortogonales: <emphasis>cu&#x00e1;ndo</emphasis> se recupera la aplicaci&#x00f3;n,
+            y <emphasis>c&#x00f3;mo</emphasis> es recuperada (qu&#x00e9; SQL es usado). &#x00a1;No las confundas! Usamos 
+            <literal>fetch</literal> para afinar el rendimiento. Podemos usar <literal>lazy</literal> para
+            definir un contrato sobre qu&#x00e9; datos est&#x00e1;n siempre disponibles en cualquier instancia separada de
+            una clase en particular.
+        </para>
+ 
+        <sect2 id="performance-fetching-lazy">
+            <title>Trabajando con asociaciones perezosas</title>
+            
+            <para>
+                Por defecto, Hibernate3 usa una recuperaci&#x00f3;n perezosa por selecci&#x00f3;n para colecciones
+                y una recuperaci&#x00f3;n por proxy perezosa para asociaciones monovaluadas. Estas pol&#x00ed;ticas por
+                defecto tienen sentido para casi todas las asociaciones en casi todas las aplicaciones.
+            </para>
+            
+            <para>
+                <emphasis>Nota:</emphasis> si estableces <literal>hibernate.default_batch_fetch_size</literal>, Hibernate
+                usar&#x00e1; la optimizaci&#x00f3;n de recuperaci&#x00f3;n en lotes para recuperaci&#x00f3;n perezosa (esta optimizaci&#x00f3;n tambi&#x00e9;n puede
+                ser habilitada a un nivel m&#x00e1;s granularizado).
+            </para>
+            
+            <para>
+                Sin embargo, la recuperaci&#x00f3;n perezosa plantea un problema del que tienes que estar al tanto. Acceder
+                a una asociaci&#x00f3;n perezosa fuera del contexto de una sesi&#x00f3;n de Hibernate abierta resultar&#x00e1; en una
+                excepci&#x00f3;n. Por ejemplo:
+            </para>
+        
+            <programlisting><![CDATA[s = sessions.openSession();
+Transaction tx = s.beginTransaction();
+            
+User u = (User) s.createQuery("from User u where u.name=:userName")
+    .setString("userName", userName).uniqueResult();
+Map permissions = u.getPermissions();
+
+tx.commit();
+s.close();
+
+Integer accessLevel = (Integer) permissions.get("accounts");  // Error!]]></programlisting>
+
+            <para>
+                Ya que la colecci&#x00f3;n de permisos no fue inicializada cuando se cerr&#x00f3; la <literal>Session</literal>,
+                la colecci&#x00f3;n no ser&#x00e1; capaz de cargar su estado. <emphasis>Hibernate no soporta la inicializaci&#x00f3;n
+                perezosa de objetos separados</emphasis>. La soluci&#x00f3;n es mover el c&#x00f3;digo que lee de la colecci&#x00f3;n
+                a justo antes que la transacci&#x00f3;n sea comprometida.
+            </para>
+    
+            <para>
+                Alternativamente, podr&#x00ed;amos usar una colecci&#x00f3;n no perezosa o asociaci&#x00f3;n, especificando
+                <literal>lazy="false"</literal> para el mapeo de asociaci&#x00f3;n. Sin embargo, est&#x00e1; pensado
+                que la inicializaci&#x00f3;n perezosa sea usada para casi todas las colecciones y asociaciones.
+                &#x00a1;Si defines demasiadas asociaciones no perezosas en tu modelo de objetos, Hibernate terminar&#x00e1;
+                necesitando recuperar la base de datos entera en cada transacci&#x00f3;n!
+            </para>
+    
+            <para>
+                Por otro lado, frecuentemente necesitamos elegir la recuperaci&#x00f3;n por uni&#x00f3;n (que es no perezosa
+                por naturaleza) en vez de la recuperaci&#x00f3;n por selecci&#x00f3;n en una transacci&#x00f3;n en particular. Veremos
+                ahora c&#x00f3;mo personalizar la estrategia de recuperaci&#x00f3;n. En Hibernate3, los mecanismos para elegir una
+                estrategia de recuperaci&#x00f3;n son id&#x00e9;nticas a las de las asociaciones monovaluadas y colecciones.
+            </para>
+        
+        </sect2>
+        
+        <sect2 id="performance-fetching-custom" revision="3">
+            <title>Afinando las estrategias de recuperaci&#x00f3;n</title>
+            
+            <para>
+                La recuperaci&#x00f3;n por selecci&#x00f3;n (la preestablecida) es extremadamente vulnerable a problemas de
+                selecci&#x00f3;n N+1, de modo querr&#x00ed;amos habilitar la recuperaci&#x00f3;n por uni&#x00f3;n (join fetching) en el
+                documento de mapeo:
+            </para>
+            
+            <programlisting><![CDATA[<set name="permissions" 
+            fetch="join">
+    <key column="userId"/>
+    <one-to-many class="Permission"/>
+</set]]></programlisting>
+
+           <programlisting><![CDATA[<many-to-one name="mother" class="Cat" fetch="join"/>]]></programlisting>
+
+            <para>
+                La estrategia de recuperaci&#x00f3;n definida en el documento de mapeo afecta a:
+            </para>
+            
+        <itemizedlist>
+             <listitem>
+                <para>
+                    las recuperaciones v&#x00ed;a <literal>get()</literal> o <literal>load()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    las recuperaciones que ocurren impl&#x00ed;citamente cuando se navega una asociaci&#x00f3;n
+                    (recuperaci&#x00f3;n perezosa)
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    las consultas de <literal>Criteria</literal>
+                </para>
+            </listitem>
+        </itemizedlist>
+
+            <para>
+                Usualmente, no usamos el documento de mapeo para personalizar la recuperaci&#x00f3;n. En cambio, mantenemos el
+                comportamiento por defecto, y lo sobrescribimos para una transacci&#x00f3;n en particular, usando
+                <literal>left join fetch</literal> en HQL. Esto le dice a Hibernate que recupere la asociaci&#x00f3;n
+                tempranamente en la primera selecci&#x00f3;n, usando una uni&#x00f3;n externa. En la API de consulta de
+                <literal>Criteria</literal>, usar&#x00ed;as <literal>setFetchMode(FetchMode.JOIN)</literal>.
+            </para>
+            
+            <para>
+                Si acaso lo deseases, podr&#x00ed;as cambiar la estrategia de recuperaci&#x00f3;n usada por
+                <literal>get()</literal> or <literal>load()</literal>; simplemente usa una consulta
+                <literal>Criteria</literal>, por ejemplo:
+            </para>
+            
+            <programlisting><![CDATA[User user = (User) session.createCriteria(User.class)
+                .setFetchMode("permissions", FetchMode.JOIN)
+                .add( Restrictions.idEq(userId) )
+                .uniqueResult();]]></programlisting>
+                
+            <para>
+                (Esto es el equivalente de Hibernate de lo que otras soluciones ORM llaman un "plan de recuperaci&#x00f3;n".)
+            </para>
+
+            <para>
+                Una forma completamente diferente de evitar problemas con selecciones N+1 es usar el cach&#x00e9; de
+                segundo nivel.
+            </para>
+
+        </sect2>
+
+        <sect2 id="performance-fetching-proxies" revision="2">
+            <title>Proxies de asociaciones de un solo extremo</title>
+
+            <para>
+                La recuperaci&#x00f3;n perezosa de colecciones est&#x00e1; implementada usando la implementaci&#x00f3;n de colecciones
+                persistentes propia de Hibernate. Sin embargo, se necesita un mecanismo diferente para un comportamiento
+                perezoso en las asociaciones de un solo extremo. La entidad objetivo de la asociaci&#x00f3;n debe ser tratada
+                con proxies. Hibernate implementa proxies de inicializaci&#x00f3;n perezosa para objetos persistentes usando
+                mejora del bytecode en tiempo de ejecuci&#x00f3;n (por medio de la excelente biblioteca CGLIB).
+            </para>
+
+            <para>
+                Por defecto, Hibernate3 genera proxies (en el arranque) para todas las clases persistentes y los usa
+                para habilitar la recuperaci&#x00f3;n perezosa de asociaciones <literal>muchos-a-uno</literal> y
+                <literal>uno-a-uno</literal>.
+            </para>
+
+            <para>
+                El fichero de mapeo puede declarar una interface a usar como interface de proxy para esa clase,
+                con el atributo <literal>proxy</literal>. Por defecto, Hibernate usa una subclase de la clase.
+                <emphasis>Nota que la clase tratada con proxies debe implementar un constructor por defecto con al
+                menos visibilidad de paquete. &#x00a1;Recomendamos este constructor para todas las clases persistentes!</emphasis>
+            </para>
+
+            <para>
+                Hay algunos puntos a tener en cuenta al extender este enfoque a clases polim&#x00f3;rficas, por ejemplo.
+            </para>
+
+            <programlisting><![CDATA[<class name="Cat" proxy="Cat">
+    ......
+    <subclass name="DomesticCat">
+        .....
+    </subclass>
+</class>]]></programlisting>
+
+            <para>
+                Primero, las instancias de <literal>Cat</literal> nunca ser&#x00e1;n objeto de un cast a 
+                <literal>DomesticCat</literal>, incluso aunque la instancia subyacente sea instancia de
+                <literal>DomesticCat</literal>:
+            </para>
+
+            <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id);  // instantiate a proxy (does not hit the db)
+if ( cat.isDomesticCat() ) {                  // hit the db to initialize the proxy
+    DomesticCat dc = (DomesticCat) cat;       // Error!
+    ....
+}]]></programlisting>
+
+            <para>
+                Segundo, es posible romper con el operador <literal>==</literal> de un proxy.
+            </para>
+
+            <programlisting><![CDATA[Cat cat = (Cat) session.load(Cat.class, id);            // instantiate a Cat proxy
+DomesticCat dc = 
+        (DomesticCat) session.load(DomesticCat.class, id);  // acquire new DomesticCat proxy!
+System.out.println(cat==dc);                            // false]]></programlisting>
+
+            <para>
+                Sin embargo, la situaci&#x00f3;n no en absoluta tan mala como parece. Aunque tenemos ahora dos referencias
+                a objetos proxy diferentes, la instancia subyacente ser&#x00e1; a&#x00fa;n el mismo objeto:
+            </para>
+
+            <programlisting><![CDATA[cat.setWeight(11.0);  // hit the db to initialize the proxy
+System.out.println( dc.getWeight() );  // 11.0]]></programlisting>
+
+            <para>
+                Tercero, no debes usar un proxy CGLIB para una clase <literal>final</literal> o una clase
+                con alg&#x00fa;n m&#x00e9;todo <literal>final</literal>.
+            </para>
+
+            <para>
+                Finalmente, si tu objeto persistente adquiere cualquier recurso bajo instanciaci&#x00f3;n
+                (por ejemplo, en inicializadores o constructores por defecto), entonces esos recursos
+                ser&#x00e1;n adquiridos tambi&#x00e9;n por el proxy. La clase del proxy es una subclase real de la clase
+                persistente.
+            </para>
+
+            <para>
+                Estos problemas se deben a limitaciones fundamentales en el modelo de herencia &#x00fa;nica de Java.
+                Si deseas evitar estos problemas cada una de tus clases persistentes deben implementar una
+                interface que declare sus m&#x00e9;todos de negocio. Debes especificar estas interfaces en el fichero
+                de mapeo. Por ejemplo:
+            </para>
+
+            <programlisting><![CDATA[<class name="CatImpl" proxy="Cat">
+    ......
+    <subclass name="DomesticCatImpl" proxy="DomesticCat">
+        .....
+    </subclass>
+</class>]]></programlisting>
+
+            <para>
+                donde <literal>CatImpl</literal> implementa la interface <literal>Cat</literal> y
+                <literal>DomesticCatImpl</literal> implementa la interface <literal>DomesticCat</literal>.
+                Entonces <literal>load()</literal> o <literal>iterate()</literal> pueden devolver instancias de
+                <literal>Cat</literal> y <literal>DomesticCat</literal>. (Nota que <literal>list()</literal>
+                usualmente no devuelve proxies.)
+            </para>
+
+            <programlisting><![CDATA[Cat cat = (Cat) session.load(CatImpl.class, catid);
+Iterator iter = session.createQuery("from CatImpl as cat where cat.name='fritz'").iterate();
+Cat fritz = (Cat) iter.next();]]></programlisting>
+
+            <para>
+                Las relaciones tambi&#x00e9;n son inicializadas perezosamente. Esto significa que debes declarar
+                cualquier propiedad como de tipo <literal>Cat</literal>, no <literal>CatImpl</literal>.
+            </para>
+
+            <para>
+                Ciertas operaciones <emphasis>no</emphasis> requieren inicializaci&#x00f3;n de proxies.
+            </para>
+
+            <itemizedlist spacing="compact">
+                <listitem>
+                    <para>
+                        <literal>equals()</literal>, si la clase persistente no sobrescribe <literal>equals()</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>hashCode()</literal>, si la clase persistente no sobrescribe
+                        <literal>hashCode()</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        El m&#x00e9;todo getter del identificador
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Hibernate detectar&#x00e1; las clase persistentes que sobrescriban <literal>equals()</literal> o
+                <literal>hashCode()</literal>.
+            </para>
+
+        </sect2>
+
+        <sect2 id="performance-fetching-initialization">
+            <title>Inicializando colecciones y proxies</title>
+
+            <para>
+                Una <literal>LazyInitializationException</literal> ser&#x00e1; lanzada por Hibernate si una colecci&#x00f3;n
+                o proxy sin inicializar es accedido fuera del &#x00e1;mbito de la <literal>Session</literal>, es decir,
+                cuando la entidad que posee la colecci&#x00f3;n o que tiene la referencia al proxy est&#x00e9; en el estado
+                separada.
+            </para>
+
+            <para>
+                A veces necesitamos asegurarnos que un proxy o colecci&#x00f3;n est&#x00e9; inicializado antes de cerrar la
+                <literal>Session</literal>. Por supuesto, siempre podemos forzar la inicializaci&#x00f3;n llamando a
+                <literal>cat.getSex()</literal> o <literal>cat.getKittens().size()</literal>, por ejemplo.
+                Pero esto es confuso a lectores del c&#x00f3;digo y no es conveniente para c&#x00f3;digo gen&#x00e9;rico.
+            </para>
+
+            <para>
+                Los m&#x00e9;todos est&#x00e1;ticos <literal>Hibernate.initialize()</literal> y
+                <literal>Hibernate.isInitialized()</literal> proveen a la aplicaci&#x00f3;n de una forma conveniente de
+                trabajar con colecciones o proxies inicializados perezosamente.
+                <literal>Hibernate.initialize(cat)</literal> forzar&#x00e1; la inicializaci&#x00f3;n de un proxy,
+                <literal>cat</literal>, en tanto su <literal>Session</literal> est&#x00e9; todav&#x00ed;a abierta.
+                <literal>Hibernate.initialize( cat.getKittens() )</literal> tiene un efecto similar para la colecci&#x00f3;n
+                de gatitos.
+            </para>
+
+            <para>
+                Otra opci&#x00f3;n es mantener la <literal>Session</literal> abierta hasta que todas las colecciones
+                y proxies necesarios hayan sido cargados. En algunas arquitecturas de aplicaci&#x00f3;n, particularmente
+                en aquellas donde el c&#x00f3;digo que accede a los datos usando Hibernate, y el c&#x00f3;digo que los usa est&#x00e1;n
+                en capas de aplicaci&#x00f3;n diferentes o procesos f&#x00ed;sicos diferentes, puede ser un problema asegurar que
+                la <literal>Session</literal> est&#x00e9; abierta cuando se inicializa una colecci&#x00f3;n. Existen dos formas
+                b&#x00e1;sicas de tratar este tema:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        En una aplicaci&#x00f3;n basada web, puede usarse un filtro de servlets para cerrar la
+                        <literal>Session</literal> s&#x00f3;lo bien al final de una petici&#x00f3;n de usuario, una
+                        vez que el rendering de la vista est&#x00e9; completa (el patr&#x00f3;n <emphasis>Sesi&#x00f3;n Abierta en
+                        Vista (Open Session in View)</emphasis>). Por supuesto, estos sitios requieren una
+                        fuerte demanda de correcci&#x00f3;n del manejo de excepciones de tu infraestructura de
+                        aplicaci&#x00f3;n. Es de una importancia vital que la <literal>Session</literal> est&#x00e9;
+                        cerrada y la transacci&#x00f3;n terminada antes de volver al usuario, incluso cuando ocurra
+                        una excepci&#x00f3;n durante el rendering de la p&#x00e1;gina. Para este enfoque, el filtro de servlet tiene
+                        que ser capaz de accceder la <literal>Session</literal>. Recomendamos que se use una variable
+                        <literal>ThreadLocal</literal> para tener la <literal>Session</literal> actual (ver
+                        el cap&#x00ed;tulo 1, <xref linkend="quickstart-playingwithcats"/>, para una implementaci&#x00f3;n de ejemplo).
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        En una aplciaci&#x00f3;n con una grada de negocios separada, la l&#x00f3;gica de negocio debe "preparar"
+                        todas las colecciones que se vayan a necesitar por la grada web antes de volver.
+                        Esto significa que la grada de negocios debe cargar todos los datos y devolver a la grada de
+                        presentaci&#x00f3;n web todos los datos que se requieran para un caso de uso en particular
+                        ya inicializados. Usualmente, la aplicaci&#x00f3;n llama a <literal>Hibernate.initialize()</literal>
+                        para cada colecci&#x00f3;n que se necesitar&#x00e1; en la grada web (esta llamada debe ocurrir antes que la
+                        sesi&#x00f3;n sea cerrada) o recupera la colecci&#x00f3;n tempranamente usando una consulta de Hibernate con una
+                        cl&#x00e1;usula <literal>FETCH</literal> o una <literal>FetchMode.JOIN</literal> en
+                        <literal>Criteria</literal>. Esto es usualmente m&#x00e1;s f&#x00e1;cil si adoptas el patr&#x00f3;n
+                        <emphasis>Comando</emphasis> en vez de un <emphasis>Fachada de Sesi&#x00f3;n</emphasis>.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Puedes tambi&#x00e9;n adjuntar un objeto cargado previamente a una nueva <literal>Session</literal>
+                        con <literal>merge()</literal> o <literal>lock()</literal> antes de acceder a colecciones
+                        no inicializadas (u otros proxies). &#x00a1;No, Hibernate no, y ciertamente <emphasis>no
+                        debe</emphasis> hacer esto autom&#x00e1;ticamente, ya que introducir&#x00ed;a sem&#x00e1;nticas de transacci&#x00f3;n ad hoc!
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                A veces no quieres inicializar una colecci&#x00f3;n grande, pero necesitas a&#x00fa;n alguna informacion sobre
+                ella (como su tama&#x00f1;o) o un subconjunto de los datos.
+            </para>
+
+            <para>
+                Puedes usar un filtro de colecciones para obtener el tama&#x00f1;o de una colecci&#x00f3;n sin inicializarla:
+            </para>
+
+            <programlisting><![CDATA[( (Integer) s.createFilter( collection, "select count(*)" ).list().get(0) ).intValue()]]></programlisting>
+
+            <para>
+                El m&#x00e9;todo <literal>createFilter()</literal> se usa tambi&#x00e9;n para recuperar eficientemente subconjuntos
+                de una colecci&#x00f3;n sin necesidad de inicializar toda la colecci&#x00f3;n:
+            </para>
+
+            <programlisting><![CDATA[s.createFilter( lazyCollection, "").setFirstResult(0).setMaxResults(10).list();]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="performance-fetching-batch">
+            <title>Usando recuperaci&#x00f3;n en lotes</title>
+
+            <para>
+                Hibernate puede hacer un uso eficiente de la recuperaci&#x00f3;n en lotes, esto es, Hibernate puede cargar
+                muchos proxies sin inicializar si se accede a un proxy (o colecciones). La recuperaci&#x00f3;n en lotes es una
+                optimizaci&#x00f3;n de la estrategia de recuperaci&#x00f3;n por selecci&#x00f3;n perezosa. Hay dos formas en que puedes afinar
+                la recuperaci&#x00f3;n en lotes: a nivel de la clase o de la colecci&#x00f3;n.
+            </para>
+
+            <para>
+                La recuperaci&#x00f3;n en lotes para clases/entidades es m&#x00e1;s f&#x00e1;cil de entender. Imagina que tienes la siguiente
+                situaci&#x00f3;n en tiempo de ejecuci&#x00f3;n: Tienes 25 instancias de <literal>Cat</literal> cargadas en una
+                <literal>Session</literal>, cada <literal>Cat</literal> tiene una referencia a su <literal>owner</literal>,
+                una <literal>Person</literal>. La clase <literal>Person</literal> est&#x00e1; mapeada con un proxy,
+                <literal>lazy="true"</literal>. Si ahora iteras a trav&#x00e9;s de todos los gatos y llamas a
+                <literal>getOwner()</literal> para cada uno, Hibernate por defecto ejecutar&#x00e1; 25 sentencias
+                <literal>SELECT</literal> para traer los due&#x00f1;os tratados con proxies. Puedes afinar este comportamiento
+                especificando un <literal>batch-size</literal> en el mapeo de <literal>Person</literal>:
+            </para>
+
+            <programlisting><![CDATA[<class name="Person" batch-size="10">...</class>]]></programlisting>
+
+            <para>
+                Hibernate ahora ejecutar&#x00e1; s&#x00f3;lo tres consultas, el patr&#x00f3;n es 10, 10, 5.
+            </para>
+
+            <para>
+                Tambi&#x00e9;n puedes habilitar la recuperaci&#x00f3;n en lotes para colecciones. Por ejemplo, si cada
+                <literal>Person</literal> tiene una colecci&#x00f3;n perezosa de <literal>Cat</literal>s, y hay 10
+                personas actualmente cargadas en la <literal>Session</literal>, iterar a trav&#x00e9;s de las 10 personas
+                generar&#x00e1; 10 <literal>SELECT</literal>s, una para cada llamada a <literal>getCats()</literal>.
+                Si habilitas la recuperaci&#x00f3;n en lotes para la colecci&#x00f3;n de <literal>cats</literal> en el mapeo de
+                <literal>Person</literal>, Hibernate puede recuperar por adelantado las colecciones:
+            </para>
+
+            <programlisting><![CDATA[<class name="Person">
+    <set name="cats" batch-size="3">
+        ...
+    </set>
+</class>]]></programlisting>
+
+            <para>
+                Con un <literal>batch-size</literal> de 3, Hibernate cargar&#x00e1; 3, 3, 3, 1 colecciones en cuatro
+                <literal>SELECT</literal>s. Una vez m&#x00e1;s, el valor del atributo depende del n&#x00fa;mero esperado de
+                colecciones sin inicializar en una <literal>Session</literal> en particular.
+            </para>
+
+            <para>
+                La recuperaci&#x00f3;n de coleccione en lotes es particularmente &#x00fa;til si tienes un &#x00e1;rbol anidado de
+                &#x00ed;tems, es decir, el t&#x00ed;pico patr&#x00f3;n de cuenta de materiales. (Aunque un <emphasis>conjunto
+                anidado</emphasis> o una <emphasis>ruta materializada</emphasis> podr&#x00ed;a ser una mejor opci&#x00f3;n
+                para &#x00e1;rboles que sean de lectura en la mayor&#x00ed;a de los casos.)
+            </para>
+
+        </sect2>
+
+        <sect2 id="performance-fetching-subselect">
+            <title>Usando recuperaci&#x00f3;n por subselecci&#x00f3;n</title>
+
+            <para>
+                Si una colecci&#x00f3;n perezosa o proxy monovaluado tiene que ser recuperado, Hibernate los carga a todos,
+                volviendo a ejecutar la consulta original en una subselecci&#x00f3;n. Esto funciona de la misma forma que
+                la recuperaci&#x00f3;n en lotes, sin carga fragmentaria.
+            </para>
+            
+            <!-- TODO: Write more about this -->
+
+        </sect2>
+        
+        <sect2 id="performance-fetching-lazyproperties">
+            <title>Usando recuperaci&#x00f3;n perezosa de propiedades</title>
+
+            <para>
+                Hibernate3 soporta la recuperaci&#x00f3;n perezosa de propiedades individuales. Esta t&#x00e9;cnica de optimizaci&#x00f3;n
+                es tambi&#x00e9;n conocida como <emphasis>grupos de recuperaci&#x00f3;n (fetch groups)</emphasis>. Por favor, nota
+                que &#x00e9;ste es mayormente un aspecto de marketing, ya que en la pr&#x00e1;ctica, optimizar lecturas de filas es
+                mucho m&#x00e1;s importante que la optimizaci&#x00f3;n de lectura de columnas. Sin embargo, cargar s&#x00f3;lo algunas
+                propiedades de una clase podr&#x00ed;a ser &#x00fa;til en casos extremos, cuando tablas heredadas tienen cientos de
+                columnas y el modelo de datos no puede ser mejorado.
+            </para>
+
+            <para>
+                Para habilitar la carga perezosa de propiedades, establece el atributo <literal>lazy</literal> en tus
+                mapeos de propiedades:
+            </para>
+
+            <programlisting><![CDATA[<class name="Document">
+       <id name="id">
+        <generator class="native"/>
+    </id>
+    <property name="name" not-null="true" length="50"/>
+    <property name="summary" not-null="true" length="200" lazy="true"/>
+    <property name="text" not-null="true" length="2000" lazy="true"/>
+</class>]]></programlisting>
+
+            <para>
+                &#x00a1;La carga perezosa de propiedades requiere la instrumentaci&#x00f3;n del bytecode en tiempo
+                de construcci&#x00f3;n! Si tus clases persistentes no son mejoradas, Hibernate ignorar&#x00e1; silenciosamente
+                la configuraci&#x00f3;n perezosa de propiedades y caer&#x00e1; en recuperaci&#x00f3;n inmediata.
+            </para>
+
+            <para>
+                Para la instrumentaci&#x00f3;n del bytecode, usa la siguiente tarea Ant:
+            </para>
+
+            <programlisting><![CDATA[<target name="instrument" depends="compile">
+    <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask">
+        <classpath path="${jar.path}"/>
+        <classpath path="${classes.dir}"/>
+        <classpath refid="lib.class.path"/>
+    </taskdef>
+
+    <instrument verbose="true">
+        <fileset dir="${testclasses.dir}/org/hibernate/auction/model">
+            <include name="*.class"/>
+        </fileset>
+    </instrument>
+</target>]]></programlisting>
+
+            <para>
+                Una forma diferente (&#x00bf;mejor?) de evitar lecturas innecesarias de columnas, al menos para
+                transacciones de s&#x00f3;lo lectura es usar las funcionalidades de proyecci&#x00f3;n de consultas HQL o Criteria.
+                Esto evita la necesidad de procesar el bytecode en tiempo de construcci&#x00f3;n y ciertamente es una soluci&#x00f3;n
+                preferida.
+            </para>
+            
+            <para>
+                Puedes forzar la usual recuperaci&#x00f3;n temprana de propiedades usando <literal>fetch all properties</literal>
+                en HQL.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="performance-cache" revision="1">
+        <title>El Cach&#x00e9; de Segundo Nivel</title>
+
+        <para>
+            Una <literal>Session</literal> de Hibernate es una cach&#x00e9; de datos persistentes a nivel de transacci&#x00f3;n.
+            Es posible configurar un cluster o cach&#x00e9; a nivel de JVM (a nivel de <literal>SessionFactory</literal>)
+            sobre una base de clase-a-clase o colecci&#x00f3;n-a-colecci&#x00f3;n. Puedes incluso enchufar una cach&#x00e9; en cluster.
+            S&#x00e9; cuidadoso. Las cach&#x00e9;s nunca est&#x00e1;n al tanto de los cambios hechos por otra aplicaci&#x00f3;n al almac&#x00e9;n persistente
+            (aunque pueden ser configurados para expirar regularmente los datos en cach&#x00e9;).
+        </para>
+        
+        <para>
+            Por defecto, Hibernate usa EHCache para caching a nivel de JVM. (El soporte a JCS ahora est&#x00e1; despreciado
+            y ser&#x00e1; quitado en una futura versi&#x00f3;n de Hibernate.) Puedes elegir una implementaci&#x00f3;n diferente estableciendo
+            el nombre de una clase que implemente <literal>org.hibernate.cache.CacheProvider</literal> usando la propiedad
+            <literal>hibernate.cache.provider_class</literal>.
+        </para>
+
+        <table frame="topbot" id="cacheproviders" revision="1">
+            <title>Proveedores de Cach&#x00e9;</title>
+            <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+            <colspec colname='c1' colwidth="1*"/>
+            <colspec colname='c2' colwidth="3*"/>
+            <colspec colname='c3' colwidth="1*"/>
+            <colspec colname='c4' colwidth="1*"/>
+            <colspec colname='c5' colwidth="1*"/>
+            <thead>
+            <row>
+              <entry>Cach&#x00e9;</entry>
+              <entry>clase del Provedor</entry>
+              <entry>Tipo</entry>
+              <entry>Cluster Seguro</entry>
+              <entry>Cach&#x00e9; de Consultas Soportado</entry>
+            </row>
+            </thead>
+            <tbody>
+            <row>
+                <entry>Hashtable (no pensado para uso en producci&#x00f3;n)</entry>
+                <entry><literal>org.hibernate.cache.HashtableCacheProvider</literal></entry>
+                <entry>memoria</entry>
+                <entry></entry>
+                <entry>s&#x00ed;</entry>
+            </row>
+            <row>
+                <entry>EHCache</entry>
+                <entry><literal>org.hibernate.cache.EhCacheProvider</literal></entry>
+                <entry>memoria, disco</entry>
+                <entry></entry>
+                <entry>s&#x00ed;</entry>
+            </row>
+            <row>
+                <entry>OSCache</entry>
+                <entry><literal>org.hibernate.cache.OSCacheProvider</literal></entry>
+                <entry>memoria, disco</entry>
+                <entry></entry>
+                <entry>s&#x00ed;</entry>
+            </row>
+            <row>
+                <entry>SwarmCache</entry>
+                <entry><literal>org.hibernate.cache.SwarmCacheProvider</literal></entry>
+                <entry>clusterizado (ip multicast)</entry>
+                <entry>s&#x00ed; (invalidaci&#x00f3;n en cluster)</entry>
+                <entry></entry>
+            </row>
+            <row>
+                <entry>TreeCache de JBoss</entry>
+                <entry><literal>org.hibernate.cache.TreeCacheProvider</literal></entry>
+                <entry>clusterizado (ip multicast), transaccional</entry>
+                <entry>s&#x00ed; (replicaci&#x00f3;n)</entry>
+                <entry>s&#x00ed; (requiere sincronizaci&#x00f3;n de reloj)</entry>
+            </row>
+            </tbody>
+            </tgroup>
+        </table>
+
+        <sect2 id="performance-cache-mapping">
+            <title>Mapeos de cach&#x00e9;</title>
+
+            <para>
+                El elemento <literal>&lt;cache&gt;</literal> de una mapeo de clase o colecci&#x00f3;n tiene la siguiente
+                forma:
+            </para>
+
+            <programlistingco>
+                <areaspec>
+                    <area id="cache1" coords="2 70"/>
+                </areaspec>
+                <programlisting><![CDATA[<cache 
+    usage="transactional|read-write|nonstrict-read-write|read-only"
+/>]]></programlisting>
+                <calloutlist>
+                    <callout arearefs="cache1">
+                        <para>
+                            <literal>usage</literal> especifica la estrategia de caching:
+                            <literal>transactional</literal>,
+                            <literal>read-write</literal>,
+                            <literal>nonstrict-read-write</literal> o
+                            <literal>read-only</literal>
+                        </para>
+                    </callout>                   
+                </calloutlist>
+            </programlistingco>
+            
+            <para>
+                Alternativamente (&#x00bf;preferiblemente?), puedes especificar los elementos
+                <literal>&lt;class-cache&gt;</literal> y <literal>&lt;collection-cache&gt;</literal> en
+                <literal>hibernate.cfg.xml</literal>.
+            </para>
+            
+            <para>
+                El atributo <literal>usage</literal> especifica una <emphasis>estrategia de concurrencia al
+                cach&#x00e9;</emphasis>.
+            </para>
+
+        </sect2>
+
+        <sect2 id="performance-cache-readonly">
+            <title>Estrategia: s&#x00f3;lo lectura (read only)</title>
+
+            <para>
+                Si tu aplicaci&#x00f3;n necesita leer pero nunca modificar las instancias de una clase persistente,
+                puede usarse un cach&#x00e9; <literal>read-only</literal>. Esta es la mejor y m&#x00e1;s simple estrategia.
+                Es incluso perfectamente segura de usar en un cluster.
+            </para>
+
+            <programlisting><![CDATA[<class name="eg.Immutable" mutable="false">
+    <cache usage="read-only"/>
+    ....
+</class>]]></programlisting>
+
+        </sect2>
+
+
+        <sect2 id="performance-cache-readwrite">
+            <title>Estrategia: lectura/escritura (read/write)</title>
+
+            <para>
+                Si la aplicaci&#x00f3;n necesita actualizar datos, un cach&#x00e9; <literal>read-write</literal> podr&#x00ed;a ser apropiado.
+                Esta estrategia de cach&#x00e9; nunca debe ser usada si se requiere nivel de aislamiento serializable de
+                transacciones. Si el cach&#x00e9; es usado en un entorno JTA, debes especificar la propiedad
+                <literal>hibernate.transaction.manager_lookup_class</literal>, mencionando una estrategia para obtener
+                el <literal>TransactionManager</literal> de JTA. En otros entornos, debes asegurarte que la transacci&#x00f3;n
+                est&#x00e9; completada cuando se llame a <literal>Session.close()</literal> o
+                <literal>Session.disconnect()</literal>. Si deseas usar esta estrategia en un cluster, debes asegurarte
+                que la implementaci&#x00f3;n de cach&#x00e9; subyacente soporta bloqueos. Los provedores de cach&#x00e9; internos
+                predeterminados <emphasis>no</emphasis> no lo soportan.
+            </para>
+
+            <programlisting><![CDATA[<class name="eg.Cat" .... >
+    <cache usage="read-write"/>
+    ....
+    <set name="kittens" ... >
+        <cache usage="read-write"/>
+        ....
+    </set>
+</class>]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="performance-cache-nonstrict">
+            <title>Estrategia: lectura/escritura no estricta (nonstrict read/write)</title>
+
+            <para>
+                Si la aplicaci&#x00f3;n necesita s&#x00f3;lo ocasionalmente actualizar datos (es decir, es extremadamente inprobable
+                que dos transacciones intenten actualizar el mismo &#x00ed;tem simult&#x00e1;neamente) y no se requiere de un
+                aislamiento de transacciones estricto, un cach&#x00e9; <literal>nonstrict-read-write</literal> podr&#x00ed;a ser
+                apropiado. Si se usa el cach&#x00e9; en un entorno JTA, debes especificar
+                <literal>hibernate.transaction.manager_lookup_class</literal>. En otros entornos, debes asegurarte que la
+                transacci&#x00f3;n se haya completado cuando se llame a <literal>Session.close()</literal> o
+                <literal>Session.disconnect()</literal>.
+            </para>
+
+        </sect2>
+
+        <sect2 id="performance-cache-transactional">
+            <title>Estrategia: transaccional</title>
+
+            <para>
+                La estrategia de cach&#x00e9; <literal>transactional</literal> brinda soporte a provedores de cach&#x00e9;s
+                completamente transaccionales como TreeCache de JBoss. Un cach&#x00e9; as&#x00ed;, puede s&#x00f3;lo ser usado en un
+                entorno JTA y debes especificar <literal>hibernate.transaction.manager_lookup_class</literal>. 
+            </para>
+
+        </sect2>
+        
+        <para>
+            Ninguno de los provedores de cach&#x00e9; soporta todas las estrategias de concurrencia al cach&#x00e9;. La siguiente
+            tabla muestra qu&#x00e9; provedores son compatibles con qu&#x00e9; estrategias de concurrencia.
+        </para>
+
+        <table frame="topbot">
+            <title>Soporte a Estrategia de Concurrencia a Cach&#x00e9;</title>
+            <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+            <colspec colname='c1' colwidth="1*"/>
+            <colspec colname='c2' colwidth="1*"/>
+            <colspec colname='c3' colwidth="1*"/>
+            <colspec colname='c4' colwidth="1*"/>
+            <colspec colname='c5' colwidth="1*"/>
+            <thead>
+            <row>
+              <entry>Cach&#x00e9;</entry>
+              <entry>read-only</entry>
+              <entry>nonstrict-read-write</entry>
+              <entry>read-write</entry>
+              <entry>transactional</entry>
+            </row>
+            </thead>
+            <tbody>
+            <row>
+                <entry>Hashtable (no pensado para uso en producci&#x00f3;n)</entry>
+                <entry>s&#x00ed;</entry>
+                <entry>s&#x00ed;</entry>
+                <entry>s&#x00ed;</entry>
+                <entry></entry>
+            </row>
+            <row>
+                <entry>EHCache</entry>
+                <entry>s&#x00ed;</entry>
+                <entry>s&#x00ed;</entry>
+                <entry>s&#x00ed;</entry>
+                <entry></entry>
+            </row>
+            <row>
+                <entry>OSCache</entry>
+                <entry>s&#x00ed;</entry>
+                <entry>s&#x00ed;</entry>
+                <entry>s&#x00ed;</entry>
+                <entry></entry>
+            </row>
+            <row>
+                <entry>SwarmCache</entry>
+                <entry>s&#x00ed;</entry>
+                <entry>s&#x00ed;</entry>
+                <entry></entry>
+                <entry></entry>
+            </row>
+            <row>
+                <entry>JBoss TreeCache</entry>
+                <entry>s&#x00ed;</entry>
+                <entry></entry>
+                <entry></entry>
+                <entry>s&#x00ed;</entry>
+            </row>
+            </tbody>
+            </tgroup>
+        </table>
+
+    </sect1>
+
+    <sect1 id="performance-sessioncache" revision="2">
+        <title>Gestionando los cach&#x00e9;s</title>
+
+        <para>
+            Siempre que pases un objeto a <literal>save()</literal>, <literal>update()</literal>
+            o <literal>saveOrUpdate()</literal> y siempre que recuperes un objeto usando
+            <literal>load()</literal>, <literal>get()</literal>, <literal>list()</literal>, 
+            <literal>iterate()</literal> o <literal>scroll()</literal>, ese objeto es agregado
+            al cach&#x00e9; interno de la <literal>Session</literal>.
+        </para>
+        <para>
+            Cuando subsecuentemente se llame a <literal>flush()</literal>, el estado de ese objeto ser&#x00e1;
+            sincronizado con la base de datos. Si no quieres que ocurra esta sincronizaci&#x00f3;n o si est&#x00e1;s
+            procesando un n&#x00fa;mero enorme de objetos y necesitas gestionar la memoria eficientemente,
+            puede usarse el m&#x00e9;todo <literal>evict()</literal> para quitar el objeto y sus colecciones
+            del cach&#x00e9; de primer nivel.
+        </para>
+        
+        <programlisting><![CDATA[ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
+while ( cats.next() ) {
+    Cat cat = (Cat) cats.get(0);
+    doSomethingWithACat(cat);
+    sess.evict(cat);
+}]]></programlisting>
+        
+        <para>
+            La <literal>Session</literal> tambi&#x00e9;n provee un m&#x00e9;todo <literal>contains()</literal> para determinar
+            si una instancia pertenece al cach&#x00e9; de la sesi&#x00f3;n.
+        </para>
+        
+        <para>
+            Para desahuciar (evict) todos los objetos del cach&#x00e9; de sesi&#x00f3;n, llama a <literal>Session.clear()</literal>.
+        </para>
+        
+        <para>
+            Para el cach&#x00e9; de segundo nivel, hay m&#x00e9;todos definidos en <literal>SessionFactory</literal> para
+            desahuciar el estado en cach&#x00e9; de una instancia, clase entera, instancia de colecci&#x00f3;n o rol
+            enter de colecci&#x00f3;n.
+        </para>
+        
+        <programlisting><![CDATA[sessionFactory.evict(Cat.class, catId); //evict a particular Cat
+sessionFactory.evict(Cat.class);  //evict all Cats
+sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
+sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections]]></programlisting>
+
+        <para>
+            El <literal>CacheMode</literal> controla c&#x00f3;mo una sesi&#x00f3;n en particular interact&#x00fa;a con el cach&#x00e9; de segundo
+            nivel.
+        </para>
+        
+        <itemizedlist>
+        <listitem>
+        <para>
+            <literal>CacheMode.NORMAL</literal> - lee &#x00ed;tems desde y escribe &#x00ed;tems hacia el cach&#x00e9; de segundo nivel
+        </para>
+        </listitem>
+        <listitem>
+        <para>
+            <literal>CacheMode.GET</literal> - lee &#x00ed;tems del cach&#x00e9; de segundo nivel, pero no escribe al cach&#x00e9; de
+            segundo nivel excepto al actualizar datos
+        </para>
+        </listitem>
+        <listitem>
+        <para>
+            <literal>CacheMode.PUT</literal> - escribe &#x00ed;tems al cach&#x00e9; de segundo nivel, pero no lee del cach&#x00e9; de segundo
+            nivel
+        </para>
+        </listitem>
+        <listitem>
+        <para>
+            <literal>CacheMode.REFRESH</literal> - escribe &#x00ed;tems al cach&#x00e9; de segundo nivel, pero no lee del cach&#x00e9; de
+            segundo nivel, salt&#x00e1;ndose el efecto de <literal>hibernate.cache.use_minimal_puts</literal>, forzando
+            un refresco del cach&#x00e9; de segundo nivel para todos los &#x00ed;tems le&#x00ed;dos de la base de datos
+        </para>
+        </listitem>
+        </itemizedlist>
+        
+        <para>
+            Para navegar por los contenidos de una regi&#x00f3;n de cach&#x00e9; de segundo nivel o de consultas, usa la API de
+            <literal>Statistics</literal>:
+        </para>
+        
+        <programlisting><![CDATA[Map cacheEntries = sessionFactory.getStatistics()
+        .getSecondLevelCacheStatistics(regionName)
+        .getEntries();]]></programlisting>
+        
+        <para>
+            Necesitar&#x00e1;s habilitar las estad&#x00ed;sticas y, opcionalmente, forzar a Hibernate para que guarde las
+            entradas del cach&#x00e9; en un formato m&#x00e1;s entendible por humanos:
+        </para>
+        
+        <programlisting><![CDATA[hibernate.generate_statistics true
+hibernate.cache.use_structured_entries true]]></programlisting>       
+                
+    </sect1>
+    
+    <sect1 id="performance-querycache" revision="1">
+        <title>El Cach&#x00e9; de Consultas</title>
+
+        <para>
+            Los conjuntos resultado de consultas tambi&#x00e9;n pueden tratarse en cach&#x00e9;. Esto s&#x00f3;lo es &#x00fa;til para
+            consultas que se ejecutan frecuentemente con los mismos par&#x00e1;metros. Para usar el cach&#x00e9; de consultas
+            primero debes habilitarlo:
+        </para>
+
+        <programlisting><![CDATA[hibernate.cache.use_query_cache true]]></programlisting>       
+        
+        <para>
+            Esta configuraci&#x00f3;n causa la creaci&#x00f3;n de dos nuevas regiones de cach&#x00e9; - una teniendo en cach&#x00e9;
+            conjuntos resultado de consulta (<literal>org.hibernate.cache.StandardQueryCache</literal>),
+            el otro teniendo timestamps de las actualizaciones m&#x00e1;s recientes a tablas consultables
+            (<literal>org.hibernate.cache.UpdateTimestampsCache</literal>). Nota que el cach&#x00e9; de consultas
+            no pone en cach&#x00e9; el estado de las entidades reales en el conjunto resultado; s&#x00f3;lo tiene en cach&#x00e9;
+            valores indentificadores y resultados de tipo de valor. De modo que el cach&#x00e9; de consultas siempre
+            debe ser usado en conjunci&#x00f3;n con el cach&#x00e9; de segundo nivel.
+        </para>
+        
+        <para>
+            La mayor&#x00ed;a de consultas no se benefician del tratamiento en cach&#x00e9;, de modo que por defecto las
+            consultas no son tratadas en cach&#x00e9;. Para habilitar el tratamiento en cach&#x00e9;, llama a
+            <literal>Query.setCacheable(true)</literal>. Esta llamada permite a la consulta buscar
+            resultados existentes en cach&#x00e9; o agregar sus resultados al cach&#x00e9; cuando se ejecuta.
+        </para>
+        
+        <para>
+            Si requieres un control finamente granularizado sobre las pol&#x00ed;ticas de expiraci&#x00f3;n del cach&#x00e9; de
+            consultas, puedes especificar una regi&#x00f3;n de cach&#x00e9; con nombre para una consulta en particular
+            llamando a <literal>Query.setCacheRegion()</literal>.
+        </para>
+        
+        <programlisting><![CDATA[List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
+    .setEntity("blogger", blogger)
+    .setMaxResults(15)
+    .setCacheable(true)
+    .setCacheRegion("frontpages")
+    .list();]]></programlisting>
+
+        <para>
+            Si la consulta debe forzar un refresco de si regi&#x00f3;n del cach&#x00e9; de consultas, debes llamar a
+            <literal>Query.setCacheMode(CacheMode.REFRESH)</literal>. Esto es particularmente &#x00fa;til en casos donde
+            los datos subyacentes pueden haber sido actualizados por medio de un proceso separado (es decir,
+            no modificados a trav&#x00e9;s de Hibernate) y permite a la aplicaci&#x00f3;n refrescar selectivamente conjuntos
+            resultado de consultas en particular. Esto es una alternativa m&#x00e1;s eficient al desahuciamiento de una
+            regi&#x00f3;n del cach&#x00e9; de consultas v&#x00ed;a <literal>SessionFactory.evictQueries()</literal>.
+        </para>
+
+    </sect1>
+
+    <sect1 id="performance-collections">
+        <title>Entendiendo el rendimiento de Colecciones</title>
+
+        <para>
+            Ya hemos llevado un buen tiempo hablando sobre colecciones.
+            En esta secci&#x00f3;n resaltaremos un par de temas m&#x00e1;s sobre c&#x00f3;mo las colecciones
+            se comportan en tiempo de ejecuci&#x00f3;n.
+        </para>
+
+        <sect2 id="performance-collections-taxonomy">
+            <title>Taxonomia</title>
+
+            <para>Hibernate define tres tipos b&#x00e1;sicos de colecciones:</para>
+
+            <itemizedlist>
+            <listitem>
+                <para>colecciones de valores</para>
+            </listitem>
+            <listitem>
+                <para>asociaciones uno a muchos</para>
+            </listitem>
+            <listitem>
+                <para>asociaciones muchos a muchos</para>
+            </listitem>
+            </itemizedlist>
+
+            <para>
+                Esta clasificaci&#x00f3;n distingue las varias tablas y relaciones de clave for&#x00e1;nea pero no nos
+                dice absolutamente todo lo que necesitamos saber sobre el modelo relacional. Para entender
+                completamente la estructura relacional y las caracter&#x00ed;sticas de rendimiento, debemos considerar
+                la estructura de la clave primaria que es usada por Hibernate para actualizar o borrar filas de
+                colecci&#x00f3;n. Esto sugiere la siguiente clasificaci&#x00f3;n:
+            </para>
+
+            <itemizedlist>
+            <listitem>
+                <para>colecciones indexadas</para>
+            </listitem>
+            <listitem>
+                <para>conjuntos (sets)</para>
+            </listitem>
+            <listitem>
+                <para>bolsas (bags)</para>
+            </listitem>
+            </itemizedlist>
+
+            <para>
+                Todas las colecciones indexadas (mapas, listas, arrays) tienen una clave primaria
+                consistente de las columnas <literal>&lt;key&gt;</literal> y <literal>&lt;index&gt;</literal>.
+                En este caso las actualizaciones de colecciones son usualmente extremadamente eficientes.
+                La clave primaria puede ser indexada f&#x00e1;cilmente y una fila en particular puede ser localizada
+                cuando Hibernate intenta actualizarla o borrarla.
+            </para>
+                        
+            <para>
+                Los conjuntos (sets) tienen una clave primaria consistente en <literal>&lt;key&gt;</literal>
+                y columnas de elemento. Esto puede ser menos eficiente para algunos tipos de elemento de
+                colecci&#x00f3;n, particularmente elementos compuestos o texto largo, o campos binarios. La base de datos
+                puede no ser capaz de indexar una clave primaria compleja eficientemente. Por otra parte,
+                para asociaciones uno a muchos o muchos a muchos, particularmente en el caso de identificadores
+                sint&#x00e9;ticos, es probable que s&#x00f3;lo sea tan eficiente. (Nota al m&#x00e1;rgen: si quieres que
+                <literal>SchemaExport</literal> realmente cree la clave primaria de un <literal>&lt;set&gt;</literal>
+                por ti, debes declarar todas las columnas como <literal>not-null="true"</literal>.)
+            </para>
+
+            <para>
+                Los mapeos de <literal>&lt;idbag&gt;</literal> definen una clave delegada, de modo que siempre
+                resulten eficientes de actualizar. De hecho, son el mejor caso.
+            </para>
+            
+            <para>
+                Los bags son el peor caso. Ya que un bag permite valores de elementos duplicados y no tiene
+                ninguna columna &#x00ed;ndice, no puede definirse ninguna clave primaria. Hibernate no tiene forma de
+                distinguir entre filas duplicadas. Hibernate resuelve este problema quitando completamente
+                (en un solo <literal>DELETE</literal>) y recreando la colecci&#x00f3;n siempre que cambia.
+                Esto podr&#x00ed;a ser muy ineficiente.
+            </para>
+
+            <para>
+                Nota que para una asociaci&#x00f3;n uno-a-muchos, la "clave primaria" puede no ser la clave
+                primaria f&#x00ed;sica de la tabla de base de datos; pero incluso en este caso, la clasificaci&#x00f3;n
+                anterior es &#x00fa;til todav&#x00ed;a. (A&#x00fa;n refleja c&#x00f3;mo Hibernate "localiza" filas individuales de la
+                colecci&#x00f3;n.)
+            </para>
+
+        </sect2>
+
+        <sect2 id="performance-collections-mostefficientupdate">
+            <title>Las listas, mapas, idbags y conjuntos son las colecciones m&#x00e1;s eficientes de actualizar</title>
+
+            <para>
+                Desde la discusi&#x00f3;n anterior, debe quedar claro que las colecciones indexadas y
+                (usualmente) los conjuntos permiten la operaci&#x00f3;n m&#x00e1;s eficiente en t&#x00e9;rminos de a&#x00f1;adir,
+                quitar y actualizar elementos.
+            </para>
+
+            <para>
+                Hay, discutiblemente, una ventaja m&#x00e1;s que las colecciones indexadas tienen sobre otros
+                conjuntos para las asociaciones muchos a muchos o colecciones de valores.  Debido a la
+                estructura de un <literal>Set</literal>, Hibernate ni siquiera actualiza una fila con
+                <literal>UPDATE</literal> cuando se "cambia" un elemento. Los cambios a un <literal>Set</literal>
+                siempre funcionan por medio de <literal>INSERT</literal> y <literal>DELETE</literal>
+                (de filas individuales). Una vez m&#x00e1;s, esta consideraci&#x00f3;n no se aplica a las asociaciones
+                uno a muchos.
+            </para>
+
+            <para>
+                Despu&#x00e9;s de observar que los arrays no pueden ser perezosos, podr&#x00ed;amos concluir que las
+                listas, mapas e idbags son los tipos m&#x00e1;s eficientes de colecciones (no inversas), con los
+                conjuntos (sets) no muy por detr&#x00e1;s. Se espera que los sets sean el tipo m&#x00e1;s com&#x00fa;n de colecci&#x00f3;n
+                en las aplicaciones de Hibernate. Esto es debido a que la sem&#x00e1;ntica de los sets es la m&#x00e1;s
+                natural en el modelo relacional.
+            </para>
+
+            <para>
+                Sin embargo, en modelos de dominio de Hibernate bien die&#x00f1;ados, usualmente vemos que la mayor&#x00ed;a
+                de las colecciones son de hecho asociaciones uno-a-muchos con <literal>inverse="true"</literal>.
+                Para estas asociaciones, la actualizaci&#x00f3;n es manejada por el extremo muchos-a-uno de la asociaci&#x00f3;n,
+                y las consideraciones de este tipo sobre el rendimiento de actualizaci&#x00f3;n de colecciones simplemente
+                no se aplican.
+            </para>
+
+        </sect2>
+
+        <sect2 id="performance-collections-mostefficentinverse">
+            <title>Los Bags y las listas son las colecciones inversas m&#x00e1;s eficientes</title>
+
+            <para>
+                Justo antes que tires a la zanja los bags para siempre, hay un caso en particular en el que
+                los bags son muchos m&#x00e1;s eficientes que los conjuntos. Para una colecci&#x00f3;n con
+                <literal>inverse="true"</literal> (el idioma est&#x00e1;ndar de relaciones uno-a-muchos bidireccionales,
+                por ejemplo) &#x00a1;podemos a&#x00f1;adir elementos a un bag o lista sin necesidad de inicializar (fetch)
+                los elementos del bag! Esto se debe a que <literal>Collection.add()</literal> o
+                <literal>Collection.addAll()</literal> siempre deben devolver true para un bag o <literal>List</literal>
+                (no como un <literal>Set</literal>). Esto puede hacer el siguiente c&#x00f3;digo com&#x00fa;n mucho m&#x00e1;s r&#x00e1;pido.
+            </para>
+
+            <programlisting><![CDATA[Parent p = (Parent) sess.load(Parent.class, id);
+    Child c = new Child();
+    c.setParent(p);
+    p.getChildren().add(c);  //no need to fetch the collection!
+    sess.flush();]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="performance-collections-oneshotdelete">
+            <title>Borrado de un solo tiro</title>
+
+            <para>
+                Ocasionalmente, borrar los elementos de una colecci&#x00f3;n uno a uno puede ser extremadamente ineficiente.
+                Hibernate no es completamente est&#x00fa;pido, de modo que sabe no hacer eso, en el caso de una colecci&#x00f3;n
+                nueva-vac&#x00ed;a (si has llamado a <literal>list.clear()</literal>, por ejemplo). En este caso, Hibernate
+                publicar&#x00e1; una sola <literal>DELETE</literal>, &#x00a1;y listo!
+            </para>
+
+            <para>
+                Sup&#x00f3;n que a&#x00f1;adimos un solo elemento a una colecci&#x00f3;n de tama&#x00f1;o veinte y luego quitamos dos elementos.
+                Hibernate publicar&#x00e1; una sentencia <literal>INSERT</literal> y dos sentencias <literal>DELETE</literal>
+                (a menos que la colecci&#x00f3;n sea un bag). Esto es ciertamente deseable.
+            </para>
+
+            <para>
+                Sin embargo, sup&#x00f3;n que quitamos dieciocho elementos, dejando dos y luego a&#x00f1;adimos tres nuevos elementos.
+                Hay dos formas posibles de proceder
+            </para>
+
+            <itemizedlist>
+            <listitem>
+                <para>borrar dieciocho filas una a una y luego insertar tres filas</para>
+            </listitem>
+            <listitem>
+                <para>quitar toda la colecci&#x00f3;n (en un solo <literal>DELETE</literal> de SQL) e insertar todos los
+                cinco elementos actuales (uno a uno)</para>
+            </listitem>
+            </itemizedlist>
+
+            <para>
+                Hibernate no es lo suficientemente inteligente para saber que la segunda opci&#x00f3;n es probablemente m&#x00e1;s
+                r&#x00e1;pida en este caso. (Y que ser&#x00ed;a probablemente indeseable para Hibernate ser tan inteligente;
+                este comportamiento podr&#x00ed;a confundir a disparadores de base de datos, etc.)
+            </para>
+
+            <para>
+                Afortunadamente, puedes forzar este comportamiento (es decir, la segunda estrategia) en cualquier
+                momento descartando (es decir, desreferenciando) la colecci&#x00f3;n original y devolviendo una colecci&#x00f3;n
+                nuevamente instanciada con todos los elementos actuales. Esto puede ser muy &#x00fa;til y potente de vez en
+                cuando.
+            </para>
+            
+            <para>
+                Por supuesto, el borrado-de-un-solo-tiro no se aplica a colecciones mapeadas
+                <literal>inverse="true"</literal>.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="performance-monitoring" revision="1">
+        <title>Monitoreando el rendimiento</title>
+
+        <para>
+            La optimizaci&#x00f3;n no es de mucho uso sin el monitoreo y el acceso a n&#x00fa;meros de rendimiento. Hibernate provee
+            un rango completo de figuras sobre sus operaciones internas. Las estad&#x00ed;sticas en Hibernate est&#x00e1;n disponibles
+            por <literal>SessionFactory</literal>.
+        </para>
+
+        <sect2 id="performance-monitoring-sf" revision="2">
+            <title>Monitoreando una SessionFactory</title>
+
+            <para>
+                Puedes acceder a las m&#x00e9;tricas de <literal>SessionFactory</literal> de dos formas.
+                Tu primera opci&#x00f3;n es llamar a <literal>sessionFactory.getStatistics()</literal> y
+                leer o mostrar por pantalla la <literal>Statistics</literal> por ti mismo.
+            </para>
+
+            <para>
+                Hibernate puede tambi&#x00e9;n usar JMX para publicar las m&#x00e9;tricas si habilitas el MBean
+                <literal>StatisticsService</literal>. Puede habilitar un solo MBean para todas tus
+                <literal>SessionFactory</literal> o una por f&#x00e1;brica. Mira el siguiente c&#x00f3;digo para
+                ejemplos de configuraci&#x00f3;n minimalistas:
+            </para>
+
+            <programlisting><![CDATA[// MBean service registration for a specific SessionFactory
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "myFinancialApp");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+stats.setSessionFactory(sessionFactory); // Bind the stats to a SessionFactory
+server.registerMBean(stats, on); // Register the Mbean on the server]]></programlisting>
+
+
+<programlisting><![CDATA[// MBean service registration for all SessionFactory's
+Hashtable tb = new Hashtable();
+tb.put("type", "statistics");
+tb.put("sessionFactory", "all");
+ObjectName on = new ObjectName("hibernate", tb); // MBean object name
+
+StatisticsService stats = new StatisticsService(); // MBean implementation
+server.registerMBean(stats, on); // Register the MBean on the server]]></programlisting>
+
+            <para>
+                POR HACER: Esto no tiene sentido: En el primer caso, recuperamos y usamos el MBean directamente.
+                En el segundo, debemos proporcionar el nombre JNDI en el que se guarda la f&#x00e1;brica de sesiones antes
+                de usarlo. Usa <literal>hibernateStatsBean.setSessionFactoryJNDIName("my/JNDI/Name")</literal>
+            </para>
+            <para>
+                Puedes (des)activar el monitoreo de una <literal>SessionFactory</literal>
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        en tiempo de configuraci&#x00f3;n, establece <literal>hibernate.generate_statistics</literal> a
+                        <literal>false</literal>
+                    </para>
+                </listitem>
+            </itemizedlist>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        en tiempo de ejecuci&#x00f3;n: <literal>sf.getStatistics().setStatisticsEnabled(true)</literal>
+                        o <literal>hibernateStatsBean.setStatisticsEnabled(true)</literal>
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Las estad&#x00ed;sticas pueden ser reajustadas program&#x00e1;ticamente usando el m&#x00e9;todo <literal>clear()</literal>.
+                Puede enviarse un resumen a un logger (nivel info) usando el m&#x00e9;todo <literal>logSummary()</literal>.
+            </para>
+
+        </sect2>
+
+        <sect2 id="performance-monitoring-metrics" revision="1">
+            <title>M&#x00e9;tricas</title>
+
+            <para>
+                Hibernate provee un n&#x00fa;mero de m&#x00e9;tricas, desde informaci&#x00f3;n muy b&#x00e1;sica a la especializada
+                s&#x00f3;lo relevante en ciertos escenarios. Todos los contadores disponibles se describen en la
+                API de la interface <literal>Statistics</literal>, en tres categor&#x00ed;as:
+            </para>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        M&#x00e9;tricas relacionadas al uso general de <literal>Session</literal> usage, tales como
+                        n&#x00fa;mero de sesiones abiertas, conexiones JDBC recuperadas, etc,
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        M&#x00e9;tricas relacionadas a las entidades, colecciones, consultas, y cach&#x00e9;s como un todo.
+                        (tambi&#x00e9;n conocidas como m&#x00e9;tricas globales).
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        M&#x00e9;tricas detalladas relacionadas a una entidad, colecci&#x00f3;n, consulta o regi&#x00f3;n de cach&#x00e9;
+                        en particular.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Por ejemplo, puedes comprobar el acceso, p&#x00e9;rdida, y radio de colocaci&#x00f3;n de entidades, colecciones
+                y consultas en el cach&#x00e9;, y el tiempo promedio que necesita una consulta. Ten en cuenta que el n&#x00fa;mero
+                de milisegundos est&#x00e1; sujeto a aproximaci&#x00f3;n en Java. Hibernate est&#x00e1; pegado a la precisi&#x00f3;n de la JVM,
+                en algunas plataformas esto podr&#x00ed;a incuso ser tener s&#x00f3;lo una exactitud de 10 segundos.
+            </para>
+
+            <para>
+                Se usan getters simples para acceder a las m&#x00e9;tricas globales (es decir, no pegadas a una entidad,
+                colecci&#x00f3;n, regi&#x00f3;n de cach&#x00e9;, etc, en particular). Puedes acceder a las m&#x00e9;tricas de una entidad,
+                colecci&#x00f3;n, regi&#x00f3;n de cach&#x00e9; en particular a trav&#x00e9;s de su nombre, y a trav&#x00e9;s de su representaci&#x00f3;n HQL
+                o SQL para las consultas. Por favor refi&#x00e9;rete al Javadoc de la API de <literal>Statistics</literal>,
+                <literal>EntityStatistics</literal>, <literal>CollectionStatistics</literal>,
+                <literal>SecondLevelCacheStatistics</literal>, y <literal>QueryStatistics</literal> para m&#x00e1;s informaci&#x00f3;n.
+                El siguiente c&#x00f3;digo muestra un ejemplo sencillo:
+            </para>
+
+            <programlisting><![CDATA[Statistics stats = HibernateUtil.sessionFactory.getStatistics();
+
+double queryCacheHitCount  = stats.getQueryCacheHitCount();
+double queryCacheMissCount = stats.getQueryCacheMissCount();
+double queryCacheHitRatio =
+  queryCacheHitCount / (queryCacheHitCount + queryCacheMissCount);
+
+log.info("Query Hit ratio:" + queryCacheHitRatio);
+
+EntityStatistics entityStats =
+  stats.getEntityStatistics( Cat.class.getName() );
+long changes =
+        entityStats.getInsertCount()
+        + entityStats.getUpdateCount()
+        + entityStats.getDeleteCount();
+log.info(Cat.class.getName() + " changed " + changes + "times"  );]]></programlisting>
+
+            <para>
+                Para trabajar sobre todas las entidades, colecciones, consultas y regiones de cach&#x00e9;s, puedes recuperar la
+                lista de nombres de entidades, colecciones, consultas y regiones de cach&#x00e9;s con los siguientes m&#x00e9;todos:
+                <literal>getQueries()</literal>, <literal>getEntityNames()</literal>,
+                <literal>getCollectionRoleNames()</literal>, y <literal>getSecondLevelCacheRegionNames()</literal>.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+</chapter>
\ No newline at end of file

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/persistent_classes.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/persistent_classes.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/persistent_classes.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/persistent_classes.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,478 @@
+<chapter id="persistent-classes" revision="2">
+    <title>Clases Persistentes</title>
+
+    <para>
+        Clases presistentes son clases en una aplicaci&#x00f3;n que implementan las
+        entidades del problema de negocio (por ejemplo, Customer y Order en una
+        aplicaci&#x00f3;n de comercio electr&#x00f3;nico). No todas las instancias de una
+        clase persistente se considera que est&#x00e9;n en el estado persistente,
+        una instancia puede en cambio ser transitoria o estar separada.
+    </para>
+
+    <para>
+        Hibernate funciona mejor si las clases siguen algunas simples reglas, tambi&#x00e9;n
+        conocidas como el modelo de programaci&#x00f3;n de Viejas Clases Java Planas
+        (Plain Old Java Object o POJO). Sin embargo, ninguna de estas reglas son
+        requerimientos r&#x00ed;gidos. En cambio, Hibernate3 asume muy poco acerca de
+        la naturaleza de tus objetos persistentes. Puedes expresar un modelo de dominio en
+        otras formas: usando &#x00e1;rboles de instancias de <literal>Map</literal>,
+        por ejemplo.
+    </para>
+
+    <sect1 id="persistent-classes-pojo">
+        <title>Un ejemplo simple de POJO</title>
+
+        <para>
+            La mayor&#x00ed;a de aplicaciones Java requieren una clase
+            representando felinos.
+        </para>
+
+        <programlisting><![CDATA[package eg;
+import java.util.Set;
+import java.util.Date;
+
+public class Cat {
+    private Long id; // identifier
+
+    private Date birthdate;
+    private Color color;
+    private char sex;
+    private float weight;
+    private int litterId;
+
+    private Cat mother;
+    private Set kittens = new HashSet();
+
+    private void setId(Long id) {
+        this.id=id;
+    }
+    public Long getId() {
+        return id;
+    }
+
+    void setBirthdate(Date date) {
+        birthdate = date;
+    }
+    public Date getBirthdate() {
+        return birthdate;
+    }
+
+    void setWeight(float weight) {
+        this.weight = weight;
+    }
+    public float getWeight() {
+        return weight;
+    }
+
+    public Color getColor() {
+        return color;
+    }
+    void setColor(Color color) {
+        this.color = color;
+    }
+
+    void setSex(char sex) {
+        this.sex=sex;
+    }
+    public char getSex() {
+        return sex;
+    }
+
+    void setLitterId(int id) {
+        this.litterId = id;
+    }
+    public int getLitterId() {
+        return litterId;
+    }
+
+    void setMother(Cat mother) {
+        this.mother = mother;
+    }
+    public Cat getMother() {
+        return mother;
+    }
+    void setKittens(Set kittens) {
+        this.kittens = kittens;
+    }
+    public Set getKittens() {
+        return kittens;
+    }
+    
+    // addKitten not needed by Hibernate
+    public void addKitten(Cat kitten) {
+    	kitten.setMother(this);
+	kitten.setLitterId( kittens.size() ); 
+        kittens.add(kitten);
+    }
+}]]></programlisting>
+
+        <para>
+            Aqu&#x00ed; hay cuatro reglas principales a seguir:
+        </para>
+
+        <sect2 id="persistent-classes-pojo-constructor" revision="1">
+            <title>Implementa un constructor sin argumentos</title>
+
+            <para>
+                <literal>Cat</literal> tiene un contructor sin argumentos. Todas las clases persistentes
+                deben tener un constructor por defecto (que puede no ser p&#x00fa;blico) de modo que Hibernate
+                pueda instanciarlas usando <literal>Constructor.newInstance()</literal>. Recomendamos fuertemente tener
+                un constructor por defecto con al menos visibilidad de <emphasis>package</emphasis> para la
+                generaci&#x00f3;n de proxies en tiempo de ejecuci&#x00f3;n en Hibernate.
+            </para>
+        </sect2>
+
+        <sect2 id="persistent-classes-pojo-identifier" revision="2">
+            <title>Provee una propiedad identificadora (opcional)</title>
+
+            <para>
+                <literal>Cat</literal> tiene una propiedad llamada <literal>id</literal>. Esta
+                propiedad mapea a la columna clave primaria de la tabla de base de datos. La propiedad
+                podr&#x00ed;a llamarse cualquierCosa, y su tipo podr&#x00ed;a haber sido cualquier tipo
+                primitivo, cualquier tipo de "envoltura" primitivo, <literal>java.lang.String</literal>
+                o <literal>java.util.Date</literal>. (Si tu tabla de base de datos heredada tiene claves
+                compuestas, puedes incluso usar una clase definida por el usuario con propiedades de
+                estos tipos, ver la secci&#x00f3;n sobre identificadores compuestos luego.)
+            </para>
+
+            <para>
+                La propiedad identificadora es estrictamente opcional. Puedes olvidarla y dejar que Hibernate
+                siga internamente la pista de los identificadores del objeto. Sin embargo, no recomendamos esto.
+            </para>
+
+            <para>
+                De hecho, alguna funcionalidad est&#x00e1; disponible s&#x00f3;lo para clases que
+                declaran una propiedad identificadora:
+            </para>
+
+            <itemizedlist spacing="compact">
+                <listitem>
+                    <para>
+                        Reasociaci&#x00f3;n transitiva de objetos separados (actualizaciones o
+                        fusiones en cascada) - ver <xref linkend="objectstate-transitive"/>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>Session.saveOrUpdate()</literal>
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>Session.merge()</literal>
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Recomendamos que declares propiedades identificadoras nombradas-consistentemente
+                en clases persistentes. Mas a&#x00fa;n, recomendamos que uses un tipo nulable
+                (es decir, no primitivo).
+            </para>
+        </sect2>
+
+        <sect2 id="persistent-classes-pojo-final">
+            <title>Prefiere las clases no finales (opcional)</title>
+            <para>
+                Un aspecto central de Hibernate, <emphasis>proxies</emphasis>, depende de que
+                las clases persistentes sean ya no finales, o sean ya la implementaci&#x00f3;n
+                de una interface que declare todos los m&#x00e9;todos p&#x00fa;blicos.
+            </para>
+            <para>
+                Puedes persistir con Hibernate clases <literal>final</literal> que no implementen una
+                interface, pero no ser&#x00e1;s capaz de usar proxies para recuperaci&#x00f3;n perezosa
+                de asociaciones, lo que limitar&#x00e1; tus opciones para afinar el rendimiento.
+            </para>
+            <para>
+                Debes tambi&#x00e9;n evitar declarar m&#x00e9;todos <literal>public final</literal>
+                en clases non-final. Si quieres usar una clase con un m&#x00e9;todo <literal>public
+                final</literal>, debes deshabilitar expl&#x00ed;citamente el uso de proxies estableciendo
+                <literal>lazy="false"</literal>.
+            </para>
+        </sect2>
+
+        <sect2 id="persistent-classes-pojo-accessors" revision="2">
+            <title>Declara m&#x00e9;todos de acceso y modificaci&#x00f3;n para los campos persistentes (opcional)</title>
+            <para>
+                <literal>Cat</literal> declara m&#x00e9;todos de acceso para todos sus campos persistente.
+                Muchas otras herramientas ORM persisten directamente variables de instancia. Creemos que
+                es mejor proveer una indirecci&#x00f3;n entre el esquema relacional y las estructuras internas de la clase.
+                Por defecto, Hibernate persiste propiedades del estilo JavaBeans, y reconoce nombres de m&#x00e9;todo
+                de la forma <literal>getFoo</literal>, <literal>isFoo</literal> y <literal>setFoo</literal>.
+                Puedes cambiar a acceso directo a campos para propiedades en particular, de ser necesario.
+            </para>
+
+            <para>
+                Las propiedades <emphasis>no</emphasis> necesitan ser declaradas p&#x00fa;blicas. Hibernate puede
+                persistir una propiedad con un par get / set <literal>protected</literal> o <literal>private</literal>.
+            </para>
+        </sect2>
+    </sect1>
+
+    <sect1 id="persistent-classes-inheritance">
+        <title>Implementando herencia</title>
+
+        <para>
+            Una subclase puede a su vez observar la primera y segunda regla. Hereda su
+            propiedad identificadora de la superclase, <literal>Cat</literal>.
+        </para>
+
+        <programlisting><![CDATA[package eg;
+
+public class DomesticCat extends Cat {
+        private String name;
+
+        public String getName() {
+                return name;
+        }
+        protected void setName(String name) {
+                this.name=name;
+        }
+}]]></programlisting>
+    </sect1>
+
+    <sect1 id="persistent-classes-equalshashcode" revision="1">
+        <title>Implementando <literal>equals()</literal> y <literal>hashCode()</literal></title>
+
+
+        <para> 
+            Tienes que sobrescribir los m&#x00e9;todos <literal>equals()</literal> y <literal>hashCode()</literal>
+            si :
+        </para>
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    piensas poner instancias de clases persistentes en un <literal>Set</literal>
+                    (la forma recomendada de representar asociaciones multivaluadas) 
+                    <emphasis>y</emphasis>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    piensas usar reasociaci&#x00f3;n de instancias separadas.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Hibernate garantiza la equivalencia de identidad persistente (fila de base de datos) y
+            identidad Java s&#x00f3;lo dentro del &#x00e1;mbito de una sesi&#x00f3;n en particular.
+            De modo que en el momento que mezclamos instancias recuperadas en sesiones diferentes,
+            debemos implementar <literal>equals()</literal> y <literal>hashCode()</literal> si
+            deseamos tener una sem&#x00e1;ntica significativa de <literal>Set</literal>s.
+        </para>
+
+        <para>
+            La forma m&#x00e1;s obvia es implementar <literal>equals()</literal>/<literal>hashCode()</literal>
+            comparando el valor identificador de ambos objetos. Si el valor es el mismo, ambos deben ser
+            la misma fila de base de datos, por lo tanto son iguales (si ambos son agregados a un
+            <literal>Set</literal>, s&#x00f3;lo tendremos un elemento en el <literal>Set</literal>).
+            Desafortunadamente, no podemos usar este enfoque con identificadores generados! Hibernate s&#x00f3;lo
+            asignar&#x00e1; valores identificadores a objetos que son persistentes, una instancia reci&#x00e9;n
+            creada no tendr&#x00e1; ning&#x00fa;n valor identificador! Adem&#x00e1;s, si una instancia no est&#x00e1;
+            salvada y est&#x00e1; actualmente en un <literal>Set</literal>, salvarla asignar&#x00e1; un
+            valor identificador al objeto. Si <literal>equals()</literal> and <literal>hashCode()</literal>
+            est&#x00e1;n basados en el valor identificador, el c&#x00f3;digo hash podr&#x00ed;a cambiar,
+            rompiendo el contrato de <literal>Set</literal>. Ver el sitio web de Hibernate para una
+            discusi&#x00f3;n completa de este problema. Observa que esto no es una incidencia de Hibernate,
+            sino la sem&#x00e1;ntica normal de Java de identidad de objeto e igualdad.
+        </para>
+
+        <para>
+            Recomendamos implementar <literal>equals()</literal> y <literal>hashCode()</literal>
+            usando <emphasis>igualdad de clave de negocio (Business key equality)</emphasis>.
+            Igualdad de clave de negocio significa que el m&#x00e9;todo <literal>equals()</literal>
+            compara s&#x00f3;lo las propiedades que forman la clave de negocio, una clave que podr&#x00ed;a
+            identificar nuestra instancia en el mundo real (una clave candidata
+            <emphasis>natural</emphasis>):
+        </para>
+
+        <programlisting><![CDATA[public class Cat {
+
+    ...
+    public boolean equals(Object other) {
+        if (this == other) return true;
+        if ( !(other instanceof Cat) ) return false;
+
+        final Cat cat = (Cat) other;
+
+        if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
+        if ( !cat.getMother().equals( getMother() ) ) return false;
+
+        return true;
+    }
+
+    public int hashCode() {
+        int result;
+        result = getMother().hashCode();
+        result = 29 * result + getLitterId();
+        return result;
+    }
+
+}]]></programlisting>
+
+        <para>
+            Nota que una clave de negocio no tiene que ser tan s&#x00f3;lida como
+            una clave primaria candidata de base de datos (ver
+            <xref linkend="transactions-basics-identity"/>). Las propiedades inmutables o
+            &#x00fa;nicas son usualmente buenas candidatas para una clave de negocio.
+        </para>
+
+    </sect1>
+
+    <sect1 id="persistent-classes-dynamicmodels">
+        <title>Modelos din&#x00e1;micos</title>
+
+        <para>
+            <emphasis>Ten en cuenta que las siguientes funcionalidades est&#x00e1;n
+            consideradas actualmente experimentales y pueden cambiar en el futuro
+            cercano.</emphasis>
+        </para>
+
+        <para>
+            Las entidades persistentes no necesariamente tienen que estar representadas
+            como clases POJO o como objetos JavaBean en tiempo de ejecuci&#x00f3;n. Hibernate
+            soporta adem&#x00e1;s modelos din&#x00e1;micos (usando <literal>Map</literal>s de
+            <literal>Map</literal>s en tiempo de ejecuci&#x00f3;n) y la representaci&#x00f3;n
+            de entidades como &#x00e1;rboles de DOM4J. Con este enfoque no escribes clases
+            persistentes, s&#x00f3;lo ficheros de mapeo.
+        </para>
+
+        <para>
+            Por defecto, Hibernate funciona en modo POJO normal. Puedes establecer una
+            representaci&#x00f3;n de entidad por defecto para una <literal>SessionFactory</literal>
+            en particular usando la opci&#x00f3;n de configuraci&#x00f3;n
+            <literal>default_entity_mode</literal>
+            (ver <xref linkend="configuration-optional-properties"/>).
+        </para>
+
+        <para>
+            Los siguientes ejemplos demuestran la representaci&#x00f3;n usando
+            <literal>Map</literal>s. Primero, en el fichero de mapeo,
+            tiene que declararse un <literal>entity-name</literal> en vez de
+            (o como agregado a) un nombre de clase:
+        </para>
+
+        <programlisting><![CDATA[<hibernate-mapping>
+
+    <class entity-name="Customer">
+
+        <id name="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="organization"
+            column="ORGANIZATION_ID"
+            class="Organization"/>
+
+        <bag name="orders"
+            inverse="true"
+            lazy="false"
+            cascade="all">
+            <key column="CUSTOMER_ID"/>
+            <one-to-many class="Order"/>
+        </bag>
+
+    </class>
+    
+</hibernate-mapping>]]></programlisting>
+
+        <para>
+            Ten en cuenta que aunque las asociaciones se declaran usando nombres
+            de clase objetivo, el tipo objetivo de una asociaci&#x00f3;n puede
+            ser adem&#x00e1;s una entidad din&#x00e1;mica en vez de un POJO. 
+        </para>
+
+        <para>
+            Despu&#x00e9;s de establecer el modo de entidad por defecto a
+            <literal>dynamic-map</literal> para la <literal>SessionFactory</literal>,
+            podemos trabajar en tiempo de ejecuci&#x00f3;n con <literal>Map</literal>s
+            de <literal>Map</literal>s:
+        </para>
+
+        <programlisting><![CDATA[Session s = openSession();
+Transaction tx = s.beginTransaction();
+Session s = openSession();
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+
+// Create an organization
+Map foobar = new HashMap();
+foobar.put("name", "Foobar Inc.");
+
+// Link both
+david.put("organization", foobar);
+
+// Save both
+s.save("Customer", david);
+s.save("Organization", foobar);
+
+tx.commit();
+s.close();]]></programlisting>
+
+        <para>
+            Las ventajas de un mapeo din&#x00e1;mico es r&#x00e1;pido tiempo de ciclo
+            de prototipado sin la necesidad de implementaci&#x00f3;n de clases de entidad.
+            Sin embargo, pierdes chequeo de tipos en tiempo de compilaci&#x00f3;n y
+            muy probablemente tratar&#x00e1;s con muchas excepciones en tiempo de ejecuci&#x00f3;n.
+            Gracias al mapeo de Hibernate, el esquema de base de datos puede estar facilmente
+            sano y normalizado, permitiendo agregar una implementaci&#x00f3;n apropiada del
+            modelo de dominio m&#x00e1;s tarde.
+        </para>
+
+        <para>
+            Los modos de representaci&#x00f3;n de entidad pueden ser establecidos
+            por <literal>Session</literal>:
+        </para>
+
+        <programlisting><![CDATA[Session dynamicSession = pojoSession.getSession(EntityMode.MAP);
+
+// Create a customer
+Map david = new HashMap();
+david.put("name", "David");
+dynamicSession.save("Customer", david);
+...
+dynamicSession.flush();
+dynamicSession.close()
+...
+// Continue on pojoSession
+]]></programlisting>
+
+
+        <para>
+            Por favor, ten en cuenta que la llamada a <literal>getSession()</literal>
+            usando un <literal>EntityMode</literal> est&#x00e1; en la API de
+            <literal>Session</literal>, no en la de <literal>SessionFactory</literal>.
+            De esta forma, la nueva <literal>Session</literal> comparte la conexi&#x00f3;n
+            JDBC, transacci&#x00f3;n y otra informaci&#x00f3;n de contexto. Esto significa
+            que no tienes que llamar a <literal>flush()</literal> ni a <literal>close()</literal>
+            en la <literal>Session</literal> secundaria, y tembi&#x00e9;n dejar el manejo
+            de la transacci&#x00f3;n y de la conexi&#x00f3;n a la unidad de trabajo primaria.
+        </para>
+
+        <para>
+            Puede encontrarse m&#x00e1;s informaci&#x00f3;n sobre las capacidades de
+            representaci&#x00f3;n XML en <xref linkend="xml"/>.
+        </para>
+
+    </sect1>
+
+    <para>
+        PORHACER: Documentar el framework de extensiones del usuario en los paquetes
+        de propiedad y proxies.
+    </para>
+
+</chapter>
+

Added: core/trunk/documentation/manual/es-ES/src/main/docbook/content/preface.xml
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/preface.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/preface.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,112 @@
+<?xml version='1.0'?>
+
+<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+    <preface id="preface" revision="2">
+        <title>Prefacio</title>
+
+
+        <para>
+            Trabajar con software orientado a objetos y una base de datos relacional puede ser
+            inc&#x00f3;modo y consumir tiempo en los entornos de empresa de hoy. Hibernate es una
+            herramienta de mapeo objeto/relacional para entornos Java. El t&#x00e9;rmino mapeo
+            objeto/relacional (MOR) hace referencia a la t&#x00e9;cnica de mapear una
+            representaci&#x00f3;n de datos desde un modelo de objetos a un modelo de datos relacional
+            con un esquema basado en SQL.
+        </para>
+
+        <para>
+            Hibernate no s&#x00f3;lo se encarga de mapear de clases Java a tablas de base de datos
+            (y de tipos de datos de Java a tipos de datos SQL), sino que tambi&#x00e9;n provee
+            facilidades de consulta y recuperaci&#x00f3;n de datos y puede reducir significativamente
+            el tiempo de desarrollo que de otra forma se gasta en el manejo de los datos en SQL y JDBC.
+        </para>
+
+        <para>
+            La meta de Hibernate es relevar al desarrollador del 95 por ciento de las tareas comunes
+            relacionadas a la programaci&#x00f3;n de la persistencia de los datos.
+            Hibernate puede no ser la mejor soluci&#x00f3;n para aplicaciones que usan solamente
+            procedimientos almacenados para implementar la l&#x00f3;gica de negocio en la base de
+            datos, es mas &#x00fa;til con modelos de dominio orientados a objetos y l&#x00f3;gica de
+            negocio en middle-tier basada en Java. Sin embargo, Hibernate ciertamente puede ayudarte
+            a quitar o encapsular c&#x00f3;digo SQL espec&#x00ed;fico de vendedor y ayudar&#x00e1;
+            con la tarea com&#x00fa;n de traducci&#x00f3;n de resultados desde una representaci&#x00f3;n
+            tabular a un grafo de objetos.
+        </para>
+
+        <para>
+            Si eres nuevo en Hibernate y lo del Mapeo Objeto/Relacional o incluso en Java,
+            sigue por favor estos pasos:
+        </para>
+
+        <orderedlist>
+            <listitem>
+                <para>
+                    Lee <xref linkend="quickstart"/> para un tutorial de 30 minutos, usando Tomcat.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Lee <xref linkend="architecture"/> para entender los entornos en los que
+                    puede ser usado Hibernate.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Dale una mirada al directorio <literal>eg/</literal> en la distribuci&#x00f3;n
+                    de Hibernate, contiene una aplicaci&#x00f3;n independiente simple.
+                    Copia tu driver JDBC al directorio <literal>lib/</literal> y edita
+                    <literal>etc/hibernate.properties</literal>, especificando los valores
+                    correctos para tu base de datos. Desde l&#x00ed;nea de comandos en el
+                    directorio de la distribuci&#x00f3;n, tipea <literal>ant eg</literal>
+                    (usando Ant), o bajo Windows, tipea <literal>build eg</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Usa esta documentaci&#x00f3;n de referencia como tu fuente de informaci&#x00f3;n
+                    primaria. Ten en consideraci&#x00f3;n leer <emphasis>Java Persistence with Hibernate</emphasis>
+                    (http://www.manning.com/bauer2) si necesitas mas ayuda con el dise&#x00f1;o
+                    de aplicaciones o si prefieres un tutorial paso a paso.
+                    Visita tambi&#x00e9;n http://caveatemptor.hibernate.org y descarga la aplicaci&#x00f3;n
+                    de ejemplo para Java Persistence with Hibernate.
+                </para>
+            </listitem>
+            <listitem>
+				<para>
+					Los FAQs son respondidos en el sitio web de Hibernate.
+				</para>
+            </listitem>
+			<listitem>
+				<para>
+                                        En el sitio web de Hibernate hay enlaces a demos de terceros, ejemplos
+                                        y tutoriales.
+				</para>
+			</listitem>
+            <listitem>
+                <para>
+                    El Area de Comunidad en el sitio web de Hibernate es una buena fuente
+                    de patrones de dise&#x00f1;o y varias soluciones de integraci&#x00f3;n
+                    (Tomcat, JBoss, Struts, EJB, etc.).
+                </para>
+            </listitem>
+         </orderedlist>
+
+         <para>
+             Si tienes preguntas, usa el foro de usuarios enlazado en el sitio web de Hibernate.
+             Tambi&#x00e9;n proveemos un sistema de seguimiento JIRA para reportes de defectos y
+             peticiones de nuevas caracter&#x00ed;sticas.
+             Si estas interesado en el desarrollo de Hibernate, &#x00fa;nete a la lista de correo
+             de desarrolladores. Si estas interesado en traducir esta documentaci&#x00f3;n a tu
+             lenguaje, cont&#x00e1;ctanos en la lista de correo de desarrolladores.
+         </para>
+
+         <para>
+             A trav&#x00e9;s de JBoss Inc. (see http://www.hibernate.org/SupportTraining/) hay
+             disponibilidad de soporte comercial de desarrollo, soporte de producci&#x00f3;n y
+             entrenamiento en Hibernate.
+             Hibernate es un proyecto de la suite de productos de c&#x00f3;digo abierto
+             JBoss Professional.
+         </para>
+
+    </preface>
\ No newline at end of file

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_criteria.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/query_criteria.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_criteria.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_criteria.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,431 @@
+<chapter id="querycriteria">
+    <title>Consultas por Criterios</title>
+
+    <para>
+        Acompa&#x00f1;a a Hibernate una API de consultas por criterios intuitiva y extensible.
+    </para>
+    
+    <sect1 id="querycriteria-creating">
+        <title>Creando una instancia de <literal>Criteria</literal></title>
+
+        <para>
+            La interface <literal>org.hibernate.Criteria</literal> representa una consulta contra
+            una clase persistente en particular. La <literal>Session</literal> es una f&#x00e1;brica de instancias
+            de <literal>Criteria</literal>.
+        </para>
+
+        <programlisting><![CDATA[Criteria crit = sess.createCriteria(Cat.class);
+crit.setMaxResults(50);
+List cats = crit.list();]]></programlisting>
+
+    </sect1>
+     
+    <sect1 id="querycriteria-narrowing">
+        <title>Estrechando el conjunto resultado</title>
+
+        <para>
+            Un criterio individual de consulta es una instancia de la interface
+            <literal>org.hibernate.criterion.Criterion</literal>. La clase
+            <literal>org.hibernate.criterion.Restrictions</literal> define m&#x00e9;todos de f&#x00e1;brica para obtener ciertos tipos
+            prefabricados de <literal>Criterion</literal>.
+        </para>
+
+        <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .add( Restrictions.like("name", "Fritz%") )
+    .add( Restrictions.between("weight", minWeight, maxWeight) )
+    .list();]]></programlisting>
+    
+        <para>
+            Las restricciones pueden ser agrupadas l&#x00f3;gicamente.
+        </para>
+
+        <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .add( Restrictions.like("name", "Fritz%") )
+    .add( Restrictions.or(
+        Restrictions.eq( "age", new Integer(0) ),
+        Restrictions.isNull("age")
+    ) )
+    .list();]]></programlisting>
+    
+       <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
+    .add( Restrictions.disjunction()
+        .add( Restrictions.isNull("age") )
+        .add( Restrictions.eq("age", new Integer(0) ) )
+        .add( Restrictions.eq("age", new Integer(1) ) )
+        .add( Restrictions.eq("age", new Integer(2) ) )
+    ) )
+    .list();]]></programlisting>
+    
+        <para>
+            Hay un gran rango de tipos de criterio prefabricados (subclases de <literal>Restrictions</literal>),
+            pero uno que es especialmente útil te deja especificar SQL directamente.
+        </para>
+
+        <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) )
+    .list();]]></programlisting>
+    
+        <para>
+            El sitio <literal>{alias}</literal> ser&#x00e1; remplazado por el alias de fila de la entidad consultada.
+        </para>
+        
+        <para>
+            Un enfoque alternativo para obtener un criterio es tomarlo de una instancia de
+            <literal>Property</literal>. Puedes crear una <literal>Property</literal> llamando a 
+            <literal>Property.forName()</literal>.
+        </para>
+    
+        <programlisting><![CDATA[
+Property age = Property.forName("age");
+List cats = sess.createCriteria(Cat.class)
+    .add( Restrictions.disjunction()
+        .add( age.isNull() )
+        .add( age.eq( new Integer(0) ) )
+        .add( age.eq( new Integer(1) ) )
+        .add( age.eq( new Integer(2) ) )
+    ) )
+    .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
+    .list();]]></programlisting>
+    
+   </sect1>
+     
+    <sect1 id="querycriteria-ordering">
+        <title>Ordenando los resultados</title>
+
+        <para>
+            Puedes ordenar los resultados usando <literal>org.hibernate.criterion.Order</literal>.
+        </para>
+
+        <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .add( Restrictions.like("name", "F%")
+    .addOrder( Order.asc("name") )
+    .addOrder( Order.desc("age") )
+    .setMaxResults(50)
+    .list();]]></programlisting>
+    
+        <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .add( Property.forName("name").like("F%") )
+    .addOrder( Property.forName("name").asc() )
+    .addOrder( Property.forName("age").desc() )
+    .setMaxResults(50)
+    .list();]]></programlisting>
+    
+    </sect1>
+    
+    <sect1 id="querycriteria-associations">
+        <title>Asociaciones</title>
+
+        <para>
+            Puedes especificar f&#x00e1;cilmente restricciones sobre las entidades relacionadas al navegar asociaciones
+            usando <literal>createCriteria()</literal>.
+        </para>
+
+        <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .add( Restrictions.like("name", "F%")
+    .createCriteria("kittens")
+        .add( Restrictions.like("name", "F%")
+    .list();]]></programlisting>
+
+        <para>
+            nota que el segundo <literal>createCriteria()</literal> devuelve una nueva instancia de
+            <literal>Criteria</literal>, que hace referencia a los elementos de la colecci&#x00f3;n
+            <literal>kittens</literal>.
+        </para>
+
+        <para>
+            La siguiente forma alternativa es útil en ciertas circunstancias.
+        </para>
+
+        <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .createAlias("kittens", "kt")
+    .createAlias("mate", "mt")
+    .add( Restrictions.eqProperty("kt.name", "mt.name") )
+    .list();]]></programlisting>
+
+        <para>
+            (<literal>createAlias()</literal> no crea una nueva instancia de
+            <literal>Criteria</literal>.)
+        </para>
+
+        <para>
+            &#x00a1;Observa que las colecciones de gatitos tenidas por las instancias de <literal>Cat</literal> devueltas
+            por las dos consultas previas <emphasis>no</emphasis> est&#x00e1;n prefiltradas por los criterios! Si deseas
+            recuperar s&#x00f3;lo los gatitos que emparejen los criterios, debes usar <literal>returnMaps()</literal>.
+        </para>
+
+        <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .createCriteria("kittens", "kt")
+        .add( Restrictions.eq("name", "F%") )
+    .returnMaps()
+    .list();
+Iterator iter = cats.iterator();
+while ( iter.hasNext() ) {
+    Map map = (Map) iter.next();
+    Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
+    Cat kitten = (Cat) map.get("kt");
+}]]></programlisting>
+
+    </sect1>
+    
+    <sect1 id="querycriteria-dynamicfetching" revision="1">
+        <title>Recuperaci&#x00f3;n din&#x00e1;mica de asociaciones</title>
+
+        <para>
+            Puedes especificar la sem&#x00e1;ntica de recuperaci&#x00f3;n de asociaciones en tiempo de ejecuci&#x00f3;n usando
+            <literal>setFetchMode()</literal>.
+        </para>
+
+        <programlisting><![CDATA[List cats = sess.createCriteria(Cat.class)
+    .add( Restrictions.like("name", "Fritz%") )
+    .setFetchMode("mate", FetchMode.EAGER)
+    .setFetchMode("kittens", FetchMode.EAGER)
+    .list();]]></programlisting>
+    
+        <para>
+            Esta consulta recuperar&#x00e1; tanto <literal>mate</literal> como <literal>kittens</literal> por
+            uni&#x00f3;n exterior (outer join). Ver <xref linkend="performance-fetching"/> para m&#x00e1;s informaci&#x00f3;n.
+        </para>
+    
+    </sect1>
+     
+    <sect1 id="querycriteria-examples">
+        <title>Consultas por ejemplos</title>
+
+        <para>
+            La clase <literal>org.hibernate.criterion.Example</literal> te permite construir un criterio de consulta
+            a partir de una instancia dada.
+        </para>
+
+        <programlisting><![CDATA[Cat cat = new Cat();
+cat.setSex('F');
+cat.setColor(Color.BLACK);
+List results = session.createCriteria(Cat.class)
+    .add( Example.create(cat) )
+    .list();]]></programlisting>
+    
+        <para>
+           Las propiedades de versi&#x00f3;n, los identificadores y las asociaciones son ignorados. Por defecto,
+           las propiedades valuadas a nulo son exclu&#x00ed;das.
+        </para>
+
+        <para>
+           Puedes ajustar c&#x00f3;mo se aplica el <literal>Example</literal>.
+        </para>
+
+        <programlisting><![CDATA[Example example = Example.create(cat)
+    .excludeZeroes()           //exclude zero valued properties
+    .excludeProperty("color")  //exclude the property named "color"
+    .ignoreCase()              //perform case insensitive string comparisons
+    .enableLike();             //use like for string comparisons
+List results = session.createCriteria(Cat.class)
+    .add(example)
+    .list();]]></programlisting>
+    
+        <para>
+            Puedes incluso usar ejemplos para colocar criterios sobre objetos asociados.
+        </para>
+
+        <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+    .add( Example.create(cat) )
+    .createCriteria("mate")
+        .add( Example.create( cat.getMate() ) )
+    .list();]]></programlisting>
+    
+    </sect1>
+    
+    <sect1 id="querycriteria-projection">
+        <title>Proyecciones, agregaci&#x00f3;n y agrupamiento</title>
+        <para>
+            La clase <literal>org.hibernate.criterion.Projections</literal> es una f&#x00e1;brica de instancias de
+            <literal>Projection</literal>. Aplicamos una proyecci&#x00f3;n a una consulta llamando a
+            <literal>setProjection()</literal>.
+        </para>
+        
+        <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+    .setProjection( Projections.rowCount() )
+    .add( Restrictions.eq("color", Color.BLACK) )
+    .list();]]></programlisting>
+    
+        <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+    .setProjection( Projections.projectionList()
+        .add( Projections.rowCount() )
+        .add( Projections.avg("weight") )
+        .add( Projections.max("weight") )
+        .add( Projections.groupProperty("color") )
+    )
+    .list();]]></programlisting>
+    
+        <para>
+            No es necesario ningún "group by" expl&#x00ed;cito en una consulta por criterios.
+            Ciertos tipos de proyecciones son definidos para ser <emphasis>proyecciones agrupadas</emphasis>,
+            que adem&#x00e1;s aparecen en la cl&#x00e1;usula SQL <literal>group by</literal>.
+        </para>
+    
+        <para>
+            Puede opcionalmente asignarse un alias a una proyecci&#x00f3;n, de modo que el valor proyectado pueda
+            ser referido en restricciones u ordenamientos. Aqu&#x00ed; hay dos formas diferentes de hacer esto:
+        </para>
+
+        <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+    .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
+    .addOrder( Order.asc("colr") )
+    .list();]]></programlisting>
+    
+        <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+    .setProjection( Projections.groupProperty("color").as("colr") )
+    .addOrder( Order.asc("colr") )
+    .list();]]></programlisting>
+    
+        <para>
+            Los m&#x00e9;todos <literal>alias()</literal> y <literal>as()</literal> simplemente envuelven una instancia
+            de proyecci&#x00f3;n en otra instancia de <literal>Projection</literal> con alias. Como un atajo, puedes asignar
+            un alias cuando agregas la proyecci&#x00f3;n a una lista de proyecciones:
+        </para>
+
+       <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+    .setProjection( Projections.projectionList()
+        .add( Projections.rowCount(), "catCountByColor" )
+        .add( Projections.avg("weight"), "avgWeight" )
+        .add( Projections.max("weight"), "maxWeight" )
+        .add( Projections.groupProperty("color"), "color" )
+    )
+    .addOrder( Order.desc("catCountByColor") )
+    .addOrder( Order.desc("avgWeight") )
+    .list();]]></programlisting>
+    
+        <programlisting><![CDATA[List results = session.createCriteria(Domestic.class, "cat")
+    .createAlias("kittens", "kit")
+    .setProjection( Projections.projectionList()
+        .add( Projections.property("cat.name"), "catName" )
+        .add( Projections.property("kit.name"), "kitName" )
+    )
+    .addOrder( Order.asc("catName") )
+    .addOrder( Order.asc("kitName") )
+    .list();]]></programlisting>
+    
+        <para>
+            Puedes tambi&#x00e9;n usar <literal>Property.forName()</literal> para expresar proyecciones:
+        </para>
+    
+        <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+    .setProjection( Property.forName("name") )
+    .add( Property.forName("color").eq(Color.BLACK) )
+    .list();]]></programlisting>
+    
+        <programlisting><![CDATA[List results = session.createCriteria(Cat.class)
+    .setProjection( Projections.projectionList()
+        .add( Projections.rowCount().as("catCountByColor") )
+        .add( Property.forName("weight").avg().as("avgWeight") )
+        .add( Property.forName("weight").max().as("maxWeight") )
+        .add( Property.forName("color").group().as("color" )
+    )
+    .addOrder( Order.desc("catCountByColor") )
+    .addOrder( Order.desc("avgWeight") )
+    .list();]]></programlisting>
+    
+    </sect1>
+    
+    <sect1 id="querycriteria-detachedqueries">
+        <title>Consultas y subconsultas separadas</title>
+        <para>
+            La clase <literal>DetachedCriteria</literal> te deja crear una consulta fuera del &#x00e1;mbito de una sesi&#x00f3;n,
+            y entonces ejecutarla luego usando alguna <literal>Session</literal> arbitraria.
+        </para>
+        
+        <programlisting><![CDATA[DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
+    .add( Property.forName("sex").eq('F') );
+    
+Session session = ....;
+Transaction txn = session.beginTransaction();
+List results = query.getExecutableCriteria(session).setMaxResults(100).list();
+txn.commit();
+session.close();]]></programlisting>
+
+        <para>
+            Tambi&#x00e9;n una <literal>DetachedCriteria</literal> puede usarse para expresar una subconsulta.
+            Las instancias de Criterion implicando subconsultas pueden obtenerse v&#x00ed;a <literal>Subqueries</literal> o
+            <literal>Property</literal>.
+        </para>
+        
+        <programlisting><![CDATA[DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
+    .setProjection( Property.forName("weight").avg() );
+session.createCriteria(Cat.class)
+    .add( Property.forName("weight").gt(avgWeight) )
+    .list();]]></programlisting>
+    
+        <programlisting><![CDATA[DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
+    .setProjection( Property.forName("weight") );
+session.createCriteria(Cat.class)
+    .add( Subqueries.geAll("weight", weights) )
+    .list();]]></programlisting>
+    
+        <para>
+            Incluso son posibles las subconsultas correlacionadas:
+        </para>
+        
+        <programlisting><![CDATA[DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
+    .setProjection( Property.forName("weight").avg() )
+    .add( Property.forName("cat2.sex").eqProperty("cat.sex") );
+session.createCriteria(Cat.class, "cat")
+    .add( Property.forName("weight").gt(avgWeightForSex) )
+    .list();]]></programlisting>
+
+    </sect1>
+
+        <!--TODO: ResultSetTransformer + aliasing. AliasToBeanTransformer allow returning arbitrary 
+                  user objects - similar to setResultClass in JDO2. General use of ResultTransformer 
+                  could also be explained. -->
+               
+    <sect1 id="query-criteria-naturalid">
+        <title>Consultas por identificador natural</title>
+        
+        <para>
+            Para la mayor&#x00ed;a de consultas, incluyendo las consultas por criterios, el cach&#x00e9; de consulta no es
+            muy eficiente, debido a que la invalidaci&#x00f3;n del cach&#x00e9; de consulta ocurre demasiado frecuentemente.
+            Sin embargo, hay un tipo especial de consulta donde podemos optimizar el algoritmo de invalidaci&#x00f3;n
+            de cach&#x00e9;: búsquedas por una clave natural constante. En algunas aplicaciones, este tipo de consulta,
+            ocurre frecuentemente. La API de criterios brinda especial provisi&#x00f3;n para este caso de uso.
+        </para>
+        
+        <para>
+            Primero, debes mapear la clave natural de tu entidad usando
+            <literal>&lt;natural-id&gt;</literal>, y habilitar el uso del cach&#x00e9; de segundo nivel.
+        </para>
+
+        <programlisting><![CDATA[<class name="User">
+    <cache usage="read-write"/>
+    <id name="id">
+        <generator class="increment"/>
+    </id>
+    <natural-id>
+        <property name="name"/>
+        <property name="org"/>
+    </natural-id>
+    <property name="password"/>
+</class>]]></programlisting>
+    
+        <para>
+            Nota que esta funcionalidad no est&#x00e1; pensada para uso con entidades con claves naturales
+            <emphasis>mutable</emphasis>.
+        </para>
+        
+        <para>
+            Seguido, habilita el cach&#x00e9; de consulta de Hibernate.
+        </para>
+        
+        <para>
+            Ahora, <literal>Restrictions.naturalId()</literal> nos permite hacer uso de el algoritmo de cach&#x00e9;
+            m&#x00e1;s eficiente.
+        </para>
+       
+        <programlisting><![CDATA[session.createCriteria(User.class)
+    .add( Restrictions.naturalId()
+        .set("name", "gavin")
+        .set("org", "hb") 
+    ).setCacheable(true)
+    .uniqueResult();]]></programlisting>
+            
+    </sect1>
+    
+</chapter>

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_hql.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/query_hql.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_hql.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_hql.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,1107 @@
+<chapter id="queryhql">
+    <title>HQL: El Lenguaje de Consulta de Hibernate</title>
+    
+    <para>
+        Hibernate est&#x00e1; equipado con un lenguaje de consulta extremadamente potente que
+        (intencionalmente en absoluto) se parece much&#x00ed;simo a SQL. Pero no te enga&#x00f1;es por la sintaxis;
+        HQL es completamente orientado a objetos, entendiendo nociones como herencia, polimorfismo
+        y asociaci&#x00f3;n.
+    </para>
+
+    <sect1 id="queryhql-casesensitivity">
+        <title>Sensibilidad a May&#x00fa;sculas</title>
+
+        <para>
+            Las consultas son insensibles a may&#x00fa;sculas, excepto para nombres de clases Java y propiedades. De modo que
+            <literal>SeLeCT</literal> es lo mismo que <literal>sELEct</literal> e igual a <literal>SELECT</literal>,
+            pero <literal>org.hibernate.eg.FOO</literal> no lo es a <literal>org.hibernate.eg.Foo</literal> y
+            <literal>foo.barSet</literal> no es igual a <literal>foo.BARSET</literal>.
+        </para>
+        
+        <para>
+            Este manual usa palabras clave HQL en min&#x00fa;sculas. Algunos usuarios encuentran las consultas con
+            palabras clave en may&#x00fa;sculas m&#x00e1;s le&#x00ed;bles, pero encontramos esta convenci&#x00f3;n fea cuando se encaja
+            en c&#x00f3;digo Java.
+        </para>
+        
+    </sect1>
+
+    <sect1 id="queryhql-from">
+        <title>La cl&#x00e1;usula from</title>
+
+        <para>
+            La consulta m&#x00e1;s simple posible de Hibernate es de la forma:
+        </para>
+        
+        <programlisting><![CDATA[from eg.Cat]]></programlisting>
+        
+        <para>
+            que simplemente devuelve todas las instancias de la clase <literal>eg.Cat</literal>.
+            Usualmente no necesitamos cualificar el nombre de la clase, ya que <literal>auto-import</literal>
+            est&#x00e1; por defecto. De modo que casi siempre escribimos solamente:
+        </para>
+        
+        <programlisting><![CDATA[from Cat]]></programlisting>
+        
+        <para>
+            La mayor&#x00ed;a del tiempo, necesitar&#x00e1;s asignar un <emphasis>alias</emphasis>, ya que querr&#x00e1;s referirte al
+            <literal>Cat</literal> en otras partes de la consulta.
+        </para>
+
+        <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+        <para>
+            Esta consulta asigna el alias <literal>cat</literal> a las instancias de <literal>Cat</literal>,
+            de modo que podr&#x00ed;amos usar ese alias luego en la consulta. La palabra clave <literal>as</literal>
+            es opcional; tambi&#x00e9;n podr&#x00ed;amos escribir:
+        </para>
+        
+        <programlisting><![CDATA[from Cat cat]]></programlisting>
+        
+        <para>
+            Pueden aparecer m&#x00fa;ltiples clases, resultando en un producto cartesiano o uni&#x00f3;n "cruzada" (cross join).
+        </para>
+        
+        <programlisting><![CDATA[from Formula, Parameter]]></programlisting>
+        <programlisting><![CDATA[from Formula as form, Parameter as param]]></programlisting>
+        
+        <para>
+            Se considera buena pr&#x00e1;ctica el nombrar los alias de consulta usando una inicial en min&#x00fa;sculas,
+            consistente con los est&#x00e1;ndares de nombrado de Java para variables locales
+            (por ejemplo, <literal>domesticCat</literal>).
+        </para>
+        
+    </sect1>
+
+    <sect1 id="queryhql-joins" revision="1">
+        <title>Asociaciones y uniones (joins)</title>
+
+        <para>
+            Podemos tambi&#x00e9;n asignar aliases a entidades asociadas, e incluso a elementos de una colecci&#x00f3;n de valores,
+            usando una <literal>join</literal>.
+        </para>
+
+        <programlisting><![CDATA[from Cat as cat 
+    inner join cat.mate as mate
+    left outer join cat.kittens as kitten]]></programlisting>
+
+        <programlisting><![CDATA[from Cat as cat left join cat.mate.kittens as kittens]]></programlisting>
+
+        <programlisting><![CDATA[from Formula form full join form.parameter param]]></programlisting>
+
+        <para>
+            Los tipos de join soportados son prestados de ANSI SQL
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    <literal>inner join</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>left outer join</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>right outer join</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>full join</literal> (no &#x00fa;til usualmente)
+                </para>
+            </listitem>
+        </itemizedlist>
+    
+        <para>
+            Las construcciones <literal>inner join</literal>, <literal>left outer join</literal> y
+            <literal>right outer join</literal> pueden ser abreviadas.
+        </para>
+
+        <programlisting><![CDATA[from Cat as cat 
+    join cat.mate as mate
+    left join cat.kittens as kitten]]></programlisting>
+    
+        <para>
+            Puedes proveer condiciones de uni&#x00f3;n extra usando la palabra clave <literal>with</literal> de HQL.
+        </para>
+
+        <programlisting><![CDATA[from Cat as cat 
+    left join cat.kittens as kitten 
+        with kitten.bodyWeight > 10.0]]></programlisting>
+
+        <para>
+            En adici&#x00f3;n, un "fetch" join permite a las asociaciones o colecciones de valores ser inicializadas
+            junto a sus objetos padres, usando una sola selecci&#x00f3;n. Esto es particularmente &#x00fa;til en el case de una
+            colecci&#x00f3;n. Efectivamente sobrescribe el outer join y las declaraciones perezosas (lazy) del fichero
+            de mapeo para asociaciones y colecciones. Ver <xref linkend="performance-fetching"/> para m&#x00e1;s
+            informaci&#x00f3;n.
+        </para>
+    
+        <programlisting><![CDATA[from Cat as cat 
+    inner join fetch cat.mate
+    left join fetch cat.kittens]]></programlisting>
+    
+        <para>
+            Usualmente a un fetch join no se necesita asign&#x00e1;rsele un alias, porque los objetos asociados no deben
+            ser usados en la cl&#x00e1;usula <literal>where</literal> (ni en cualquier otra cl&#x00e1;usula). Adem&#x00e1;s, los objetos
+            asociados no son devueltos directamente en los resultados de consulta. En cambio, pueden ser accedidos
+            v&#x00ed;a el objeto padre. La &#x00fa;nica raz&#x00f3;n por la que necesitar&#x00ed;amos un alias es estamos uniendo recursivamente
+            otra colecci&#x00f3;n:
+        </para>
+        
+        <programlisting><![CDATA[from Cat as cat 
+    inner join fetch cat.mate
+    left join fetch cat.kittens child
+    left join fetch child.kittens]]></programlisting>
+    
+        <para>
+            Nota que la construcci&#x00f3;n <literal>fetch</literal> no puede usarse en consultas llamadas usando
+            <literal>scroll()</literal> o <literal>iterate()</literal>. Ni debe usarse <literal>fetch</literal>
+            junto con <literal>setMaxResults()</literal> o <literal>setFirstResult()</literal>. Tampoco puede usarse
+            <literal>fetch</literal> junto a una condici&#x00f3;n <literal>with</literal> ad hoc. Es posible crear
+            un producto cartesiano trayendo por join m&#x00e1;s de una colecci&#x00f3;n en una colecci&#x00f3;n, as&#x00ed; que ten cuidado en
+            este caso. Traer por join m&#x00fa;ltiples roles de colecci&#x00f3;n tambi&#x00e9;n da a veces resultados inesperados para mapeos
+            de bag, as&#x00ed; que s&#x00e9; cuidadoso sobre c&#x00f3;mo formular tus consultas en este caso. Finalmente, nota que
+            <literal>full join fetch</literal> y <literal>right join fetch</literal> no son significativos.
+        </para>
+        
+        <para>
+            Si est&#x00e1;s usando recuperaci&#x00f3;n perezosa a nivel de propiedad (con instrumentaci&#x00f3;n de bytecode), es posible
+            forzar a Hibernate a traer las propiedades perezosas inmediatamente (en la primera consulta) usando
+            <literal>fetch all properties</literal>.
+        </para>
+        
+        <programlisting><![CDATA[from Document fetch all properties order by name]]></programlisting>
+        <programlisting><![CDATA[from Document doc fetch all properties where lower(doc.name) like '%cats%']]></programlisting>
+            
+    </sect1>
+
+    <sect1 id="queryhql-select">
+        <title>La cl&#x00e1;usula select</title>
+
+        <para>
+            La cl&#x00e1;usula <literal>select</literal> escoge qu&#x00e9; objetos y propiedades devolver in el conjunto resultado
+            de la consulta. Considera:
+        </para>
+
+        <programlisting><![CDATA[select mate 
+from Cat as cat 
+    inner join cat.mate as mate]]></programlisting>
+
+        <para>
+            La consulta seleccionar&#x00e1; <literal>mate</literal>s de otros <literal>Cat</literal>s.
+            Realmente, puedes expresar esta consulta en un forma m&#x00e1;s compacta como:
+        </para>
+
+        <programlisting><![CDATA[select cat.mate from Cat cat]]></programlisting>
+
+        <para>
+            Las consultas pueden devolver propiedades de cualquier tipo de valor incluyendo propiedades de
+            tipo componente:
+        </para>
+
+        <programlisting><![CDATA[select cat.name from DomesticCat cat
+where cat.name like 'fri%']]></programlisting>
+
+        <programlisting><![CDATA[select cust.name.firstName from Customer as cust]]></programlisting>
+
+        <para>
+            Las consultas pueden devolver m&#x00fa;ltiples objetos y/o propiedades como un array de tipo
+            <literal>Object[]</literal>,
+        </para>
+
+        <programlisting><![CDATA[select mother, offspr, mate.name 
+from DomesticCat as mother
+    inner join mother.mate as mate
+    left outer join mother.kittens as offspr]]></programlisting>
+    
+        <para>
+            o como una <literal>List</literal>,
+        </para>
+        
+        <programlisting><![CDATA[select new list(mother, offspr, mate.name)
+from DomesticCat as mother
+    inner join mother.mate as mate
+    left outer join mother.kittens as offspr]]></programlisting>
+    
+        <para>
+            o como un objeto real Java de tipo seguro,
+        </para>
+        
+        <programlisting><![CDATA[select new Family(mother, mate, offspr)
+from DomesticCat as mother
+    join mother.mate as mate
+    left join mother.kittens as offspr]]></programlisting>
+        
+        <para>
+            asumiendo que la clase <literal>Family</literal> tiene un constructor apropiado.
+        </para>
+        
+        <para>
+            Puedes asignar aliases para seleccionar expresiones usando <literal>as</literal>:
+        </para>
+
+        <programlisting><![CDATA[select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n
+from Cat cat]]></programlisting>
+
+        <para>
+            Esto es lo m&#x00e1;s &#x00fa;til cuando se usa junto con <literal>select new map</literal>:
+        </para>
+            
+        <programlisting><![CDATA[select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n )
+from Cat cat]]></programlisting>
+
+        <para>
+            Esta consulta devuelve un <literal>Map</literal> de aliases a valores seleccionados.
+        </para>
+         
+    </sect1>
+
+    <sect1 id="queryhql-aggregation">
+        <title>Funciones de agregaci&#x00f3;n</title>
+
+        <para>
+            Las consultas HQL pueden incluso devolver resultados de funciones de agregaci&#x00f3;n sobre propiedades:
+        </para>
+
+        <programlisting><![CDATA[select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)
+from Cat cat]]></programlisting>
+
+<!-- NO LONGER SUPPORTED
+        <para>
+            Collections may also appear inside aggregate functions in the <literal>select</literal> 
+            clause.
+        </para>
+
+        <programlisting><![CDATA[select cat, count( elements(cat.kittens) ) 
+from Cat cat group by cat]]></programlisting>
+-->
+
+        <para>
+            Las funciones de agregaci&#x00f3;n soportadas son
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    <literal>avg(...), sum(...), min(...), max(...)</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>count(*)</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>count(...), count(distinct ...), count(all...)</literal>
+                </para>
+            </listitem>
+        </itemizedlist>
+    
+        <para>
+            Puedes usar operadores aritm&#x00e9;ticos, concatenaci&#x00f3;n, y funciones SQL reconocidas en la cl&#x00e1;usula select:
+        </para>
+        
+        <programlisting><![CDATA[select cat.weight + sum(kitten.weight) 
+from Cat cat 
+    join cat.kittens kitten
+group by cat.id, cat.weight]]></programlisting>
+    
+        <programlisting><![CDATA[select firstName||' '||initial||' '||upper(lastName) from Person]]></programlisting>
+    
+        <para>
+            Las palabras clave <literal>distinct</literal> y <literal>all</literal> pueden ser usadas y tienen las misma
+            sem&#x00e1;ntica que en SQL.
+        </para>
+
+        <programlisting><![CDATA[select distinct cat.name from Cat cat
+
+select count(distinct cat.name), count(cat) from Cat cat]]></programlisting>
+
+    </sect1>
+    
+    <sect1 id="queryhql-polymorphism">
+        <title>Consultas polim&#x00f3;rficas</title>
+
+        <para>
+            Una consulta como:
+        </para>
+
+        <programlisting><![CDATA[from Cat as cat]]></programlisting>
+
+        <para>
+            devuelve instancias no s&#x00f3;lo de <literal>Cat</literal>, sino tambi&#x00e9;n de subclases como
+            <literal>DomesticCat</literal>. Las consultas de Hibernate pueden mencionar <emphasis>cualquier</emphasis>
+            clase o interface Java en la cl&#x00e1;usula <literal>from</literal>. La consulta devolver&#x00e1; instancias de todas
+            las clases persistentes que extiendan esa clase o implementen la interface. La siguiente consulta devolver&#x00ed;a
+            todos los objetos persistentes.
+        </para>
+        
+        <programlisting><![CDATA[from java.lang.Object o]]></programlisting>
+        
+        <para>
+            La interface <literal>Named</literal> podr&#x00ed;a ser implementada por varias clases persistentes:
+        </para>
+        
+        <programlisting><![CDATA[from Named n, Named m where n.name = m.name]]></programlisting>
+        
+        <para>
+            Nota que estas dos &#x00fa;ltimas consultas requerir&#x00e1;n m&#x00e1;s de un <literal>SELECT</literal> SQL. Esto significa
+            que la cl&#x00e1;usula <literal>order by</literal> no ordenar&#x00e1; correctamente todo el conjunto resultado.
+            (Significa adem&#x00e1;s que no puedes llamar estas consulta usando <literal>Query.scroll()</literal>.)
+        </para>
+        
+    </sect1>
+
+    <sect1 id="queryhql-where">
+        <title>La cl&#x00e1;usula where</title>
+
+        <para>
+            La cl&#x00e1;usula where te permite estrechar la lista de instancias devueltas. Si no existe ning&#x00fa;n alias.
+            puedes referirte a las propiedades por nombre:
+        </para>
+
+        <programlisting><![CDATA[from Cat where name='Fritz']]></programlisting>
+        
+        <para>
+                Si existe un alias, usan un nombre cualificado de propiedad:
+        </para>
+        
+        <programlisting><![CDATA[from Cat as cat where cat.name='Fritz']]></programlisting>
+
+        <para>
+            devuelve las instancias de <literal>Cat</literal> llamadas 'Fritz'.
+        </para>
+
+        <programlisting><![CDATA[select foo 
+from Foo foo, Bar bar
+where foo.startDate = bar.date]]></programlisting>
+
+        <para>
+            devolver&#x00e1; todas las instancias de <literal>Foo</literal> para las cuales exista una instancia
+            de <literal>bar</literal> con una propiedad <literal>date</literal> igual a la propiedad
+            <literal>startDate</literal> del <literal>Foo</literal>. Las expresiones de ruta compuestas hacen
+            la cl&#x00e1;usula <literal>where</literal> extremadamente potente. Considera:
+        </para>
+
+        <programlisting><![CDATA[from Cat cat where cat.mate.name is not null]]></programlisting>
+
+        <para>
+            Esta consulta se traduce en una consulta SQL con una uni&#x00f3;n de tabla (interna). Si fueses a escribir algo como
+        </para>
+
+        <programlisting><![CDATA[from Foo foo  
+where foo.bar.baz.customer.address.city is not null]]></programlisting>
+
+        <para>
+            terminar&#x00ed;as con una consulta que requerir&#x00ed;a cuatro uniones de tablas en SQL.
+        </para>
+
+        <para>
+            El operador <literal>=</literal> puede ser usado para comparar no s&#x00f3;lo propiedades, sino tambi&#x00e9;n instancias:
+        </para>
+
+        <programlisting><![CDATA[from Cat cat, Cat rival where cat.mate = rival.mate]]></programlisting>
+
+        <programlisting><![CDATA[select cat, mate 
+from Cat cat, Cat mate
+where cat.mate = mate]]></programlisting>
+
+        <para>
+            La propiedad especial (en min&#x00fa;sculas) <literal>id</literal> puede ser usada para referenciar el identificador
+            &#x00fa;nico de un objeto. (Tambi&#x00e9;n puedes usar su nombre de propiedad.)
+        </para>
+
+        <programlisting><![CDATA[from Cat as cat where cat.id = 123
+
+from Cat as cat where cat.mate.id = 69]]></programlisting>
+
+        <para>
+            La segunda consulta es eficiente. &#x00a1;No se requiere ninguna uni&#x00f3;n de tablas!
+        </para>
+
+        <para>
+            Tambi&#x00e9;n pueden ser usadas las propiedades de identificadores compuestos. Sup&#x00f3;n que <literal>Person</literal> 
+            tiene un identificador compuesto consistente en <literal>country</literal> y <literal>medicareNumber</literal>.
+        </para>
+
+        <programlisting><![CDATA[from bank.Person person
+where person.id.country = 'AU' 
+    and person.id.medicareNumber = 123456]]></programlisting>
+
+        <programlisting><![CDATA[from bank.Account account
+where account.owner.id.country = 'AU' 
+    and account.owner.id.medicareNumber = 123456]]></programlisting>
+
+        <para>
+            Una vez m&#x00e1;s, la segunda consulta no requiere ninguna uni&#x00f3;n de tablas.
+        </para>
+            
+        <para>
+            Asimismo, la propiedad especial <literal>class</literal> acccede al valor discriminador de una instancia en
+            el caso de persistencia polim&#x00f3;rfica. Un nombre de clase Java embebido en la cl&#x00e1;usula where ser&#x00e1;
+            traducido a su valor discriminador.
+        </para>
+
+        <programlisting><![CDATA[from Cat cat where cat.class = DomesticCat]]></programlisting>
+        
+        <para>
+            Puedes tambi&#x00e9;n especificar propiedades de componentes o tipos compuestos de usuario (y de componentes
+            de componentes, etc). Nunca intentes usar una expresi&#x00f3;n de ruta que termine en una propiedad de tipo
+            componente (al contrario de una propiedad de un componente). Por ejemplo, si <literal>store.owner</literal>
+            es una entidad con un componente <literal>address</literal>
+        </para>
+
+        <programlisting><![CDATA[store.owner.address.city    // okay
+store.owner.address         // error!]]></programlisting>
+
+        <para>
+            Un tipo "any" tiene las propiedades especiales <literal>id</literal> y <literal>class</literal>,
+            permit&#x00e9;ndonos expresar un join en la siguiente forma (donde <literal>AuditLog.item</literal> es una
+            propiedad mapeada con <literal>&lt;any&gt;</literal>).
+        </para>
+       
+        <programlisting><![CDATA[from AuditLog log, Payment payment 
+where log.item.class = 'Payment' and log.item.id = payment.id]]></programlisting>
+    
+        <para>
+            Nota que <literal>log.item.class</literal> y <literal>payment.class</literal> har&#x00ed;an referencia a
+            los valores de columnas de base de datos completamente diferentes en la consulta anterior.
+        </para>
+        
+    </sect1>
+
+    <sect1 id="queryhql-expressions">
+        <title>Expresiones</title>
+
+        <para>
+            Las expresiones permitidas en la cl&#x00e1;usula <literal>where</literal> incluyen la mayor&#x00ed;a del tipo de cosas
+            que podr&#x00ed;as escribir en SQL:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    operadores matem&#x00e1;ticos <literal>+, -, *, /</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    operadores de comparaci&#x00f3;n binarios <literal>=, &gt;=, &lt;=, &lt;&gt;, !=, like</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    operadores l&#x00f3;gicos <literal>and, or, not</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Par&#x00e9;ntesis <literal>( )</literal>, indicando agrupaci&#x00f3;n
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>in</literal>,
+                    <literal>not in</literal>,
+                    <literal>between</literal>,
+                    <literal>is null</literal>,
+                    <literal>is not null</literal>,
+                    <literal>is empty</literal>,
+                    <literal>is not empty</literal>,
+                    <literal>member of</literal> y
+                    <literal>not member of</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Caso "simple", <literal>case ... when ... then ... else ... end</literal>,
+                    y caso "buscado", <literal>case when ... then ... else ... end</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    concatenaci&#x00f3;n de cadenas <literal>...||...</literal> o <literal>concat(...,...)</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>current_date()</literal>, <literal>current_time()</literal>,
+                    <literal>current_timestamp()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+					<literal>second(...)</literal>, <literal>minute(...)</literal>, 
+					<literal>hour(...)</literal>, <literal>day(...)</literal>, 
+					<literal>month(...)</literal>, <literal>year(...)</literal>,
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Cualquier funci&#x00f3;n u operador definido por EJB-QL 3.0: <literal>substring(), trim(),
+                    lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>coalesce()</literal> y <literal>nullif()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>str()</literal> para convertir valores num&#x00e9;ricos o temporales a una cadena legible.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>cast(... as ...)</literal>, donde el segundo argumento es el nombre de un tipo Hibernate
+                    , y <literal>extract(... from ...)</literal> si <literal>cast()</literal> y
+                    <literal>extract()</literal> fuesen soportados por la base de datos subyacente.
+                </para>
+            </listitem>
+
+
+            <listitem>
+                <para>
+                    la funci&#x00f3;n <literal>index()</literal> de HQL, que se aplica a alias de una colecci&#x00f3;n
+                    indexada unida.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    funciones de HQL que tomen expresiones de ruta valuadas en colecciones: <literal>size(), 
+                    minelement(), maxelement(), minindex(), maxindex()</literal>, junto a las funciones especiales
+                    <literal>elements()</literal> and <literal>indices</literal> que pueden ser cuantificadas usando
+                    <literal>some, all, exists, any, in</literal>.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    Cualquier funci&#x00f3;n escalar SQL soportada por la base de datos como <literal>sign()</literal>, 
+                    <literal>trunc()</literal>, <literal>rtrim()</literal>, <literal>sin()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    par&#x00e1;metros posicionales JDBC <literal>?</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    par&#x00e1;metros con nombre <literal>:name</literal>, <literal>:start_date</literal>, <literal>:x1</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    literales SQL <literal>'foo'</literal>, <literal>69</literal>, <literal>6.66E+2</literal>,
+                    <literal>'1970-01-01 10:00:01.0'</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    constantes Java <literal>public static final</literal> <literal>eg.Color.TABBY</literal>
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            <literal>in</literal> y <literal>between</literal> pueden usarse como sigue:
+        </para>
+
+        <programlisting><![CDATA[from DomesticCat cat where cat.name between 'A' and 'B']]></programlisting>
+
+        <programlisting><![CDATA[from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+        <para>
+            y pueden escribirse las formas negadas
+        </para>
+
+        <programlisting><![CDATA[from DomesticCat cat where cat.name not between 'A' and 'B']]></programlisting>
+
+        <programlisting><![CDATA[from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )]]></programlisting>
+
+        <para>
+            Asimismo, <literal>is null</literal> y <literal>is not null</literal> pueden ser usadas para comprobar
+            valores nulos.
+        </para>
+
+        <para>
+            Los booleanos pueden ser f&#x00e1;cilmente usados en expresiones declarando substituciones de consulta HQL
+            en la configuraci&#x00f3;n de Hibernate:
+        </para>
+
+        <programlisting><![CDATA[<property name="hibernate.query.substitutions">true 1, false 0</property>]]></programlisting>
+
+        <para>
+            Esto remplazar&#x00e1; las palabras clave <literal>true</literal> y <literal>false</literal> con los literales
+            <literal>1</literal> y <literal>0</literal> en el SQL traducido de este HQL:
+        </para>
+
+        <programlisting><![CDATA[from Cat cat where cat.alive = true]]></programlisting>
+
+        <para>
+            Puedes comprobar el tama&#x00f1;o de una colecci&#x00f3;n con la propiedad especial <literal>size</literal>, o la funci&#x00f3;n
+            especial <literal>size()</literal>.
+        </para>
+
+        <programlisting><![CDATA[from Cat cat where cat.kittens.size > 0]]></programlisting>
+
+        <programlisting><![CDATA[from Cat cat where size(cat.kittens) > 0]]></programlisting>
+
+        <para>
+            Para colecciones indexadas, puedes referirte a los &#x00ed;ndices m&#x00e1;ximo y m&#x00ed;nimo usando las funciones
+            <literal>minindex</literal> y <literal>maxindex</literal>. Similarmente, puedes referirte a los elementos
+            m&#x00e1;ximo y m&#x00ed;nimo de una colecci&#x00f3;n de tipo b&#x00e1;sico usando las funciones
+            <literal>minelement</literal> y <literal>maxelement</literal>.
+        </para>
+        
+        <programlisting><![CDATA[from Calendar cal where maxelement(cal.holidays) > current_date]]></programlisting>
+        
+        <programlisting><![CDATA[from Order order where maxindex(order.items) > 100]]></programlisting>
+
+        <programlisting><![CDATA[from Order order where minelement(order.items) > 10000]]></programlisting>
+        
+        <para>
+            Las funciones SQL <literal>any, some, all, exists, in</literal> est&#x00e1;n soportadas cuando se les pasa
+            el conjunto de elementos o &#x00ed;ndices de una colecci&#x00f3;n (funciones <literal>elements</literal> y
+            <literal>indices</literal>) o el resultado de una subconsulta (ver debajo).
+        </para>
+
+        <programlisting><![CDATA[select mother from Cat as mother, Cat as kit
+where kit in elements(foo.kittens)]]></programlisting>
+
+        <programlisting><![CDATA[select p from NameList list, Person p
+where p.name = some elements(list.names)]]></programlisting>
+
+        <programlisting><![CDATA[from Cat cat where exists elements(cat.kittens)]]></programlisting>
+
+        <programlisting><![CDATA[from Player p where 3 > all elements(p.scores)]]></programlisting>
+
+        <programlisting><![CDATA[from Show show where 'fizard' in indices(show.acts)]]></programlisting>
+
+        <para>
+            Nota que estas construcciones - <literal>size</literal>, <literal>elements</literal>,
+            <literal>indices</literal>, <literal>minindex</literal>, <literal>maxindex</literal>,
+            <literal>minelement</literal>, <literal>maxelement</literal> - pueden ser usadas solamente
+            en la cl&#x00e1;usula where en Hibernate3.
+        </para>
+        
+        <para>
+            Los elementos de colecciones indexadas (arrays, listas, mapas) pueden ser referidos por &#x00ed;ndice
+            (en una cl&#x00e1;usula where solamente):
+        </para>
+        
+        <programlisting><![CDATA[from Order order where order.items[0].id = 1234]]></programlisting>
+
+        <programlisting><![CDATA[select person from Person person, Calendar calendar
+where calendar.holidays['national day'] = person.birthDay
+    and person.nationality.calendar = calendar]]></programlisting>
+
+        <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11]]></programlisting>
+
+        <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ maxindex(order.items) ] = item and order.id = 11]]></programlisting>
+
+        <para>
+            La expresi&#x00f3;n dentro de <literal>[]</literal> puede incluso ser una expresi&#x00f3;n aritm&#x00e9;tica.
+        </para>
+        
+        <programlisting><![CDATA[select item from Item item, Order order
+where order.items[ size(order.items) - 1 ] = item]]></programlisting>
+        
+        <para>
+            HQL provee adem&#x00e1;s el funci&#x00f3;n prefabricada <literal>index()</literal>, para elementos de una
+            asociaci&#x00f3;n uno-a-muchos o colecci&#x00f3;n de valores.
+        </para>
+
+        <programlisting><![CDATA[select item, index(item) from Order order 
+    join order.items item
+where index(item) < 5]]></programlisting>
+
+        <para>
+            Pueden usarse las funciones SQL escalares soportadas por la base de datos subyacente
+        </para>
+
+        <programlisting><![CDATA[from DomesticCat cat where upper(cat.name) like 'FRI%']]></programlisting>
+
+        <para>
+            Si a&#x00fa;n no est&#x00e1;s convencido de todo esto, piensa cu&#x00e1;nto m&#x00e1;s largo y menos le&#x00ed;ble ser&#x00ed;a la siguiente
+            consulta en SQL:
+        </para>
+
+        <programlisting><![CDATA[select cust
+from Product prod,
+    Store store
+    inner join store.customers cust
+where prod.name = 'widget'
+    and store.location.name in ( 'Melbourne', 'Sydney' )
+    and prod = all elements(cust.currentOrder.lineItems)]]></programlisting>
+
+        <para>
+            <emphasis>Ayuda:</emphasis> algo como
+        </para>
+
+        <programlisting><![CDATA[SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
+FROM customers cust,
+    stores store,
+    locations loc,
+    store_customers sc,
+    product prod
+WHERE prod.name = 'widget'
+    AND store.loc_id = loc.id
+    AND loc.name IN ( 'Melbourne', 'Sydney' )
+    AND sc.store_id = store.id
+    AND sc.cust_id = cust.id
+    AND prod.id = ALL(
+        SELECT item.prod_id
+        FROM line_items item, orders o
+        WHERE item.order_id = o.id
+            AND cust.current_order = o.id
+    )]]></programlisting>
+
+    </sect1>
+
+    <sect1 id="queryhql-ordering">
+        <title>La cl&#x00e1;usula order by</title>
+
+        <para>
+            La lista devuelta por una consulta puede ser ordenada por cualquier propiedad de una clase devuelta
+            o componentes:
+        </para>
+
+        <programlisting><![CDATA[from DomesticCat cat
+order by cat.name asc, cat.weight desc, cat.birthdate]]></programlisting>
+
+        <para>
+            Los <literal>asc</literal> o <literal>desc</literal> opcionales indican ordenamiento ascendente o
+            descendente respectivamente.
+        </para>
+    </sect1>
+
+    <sect1 id="queryhql-grouping">
+        <title>La cl&#x00e1;usula group by</title>
+
+        <para>
+            Una consulta que devuelve valores agregados puede ser agrupada por cualquier propiedad de una clase
+            devuelta o componentes:
+        </para>
+
+        <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat) 
+from Cat cat
+group by cat.color]]></programlisting>
+
+        <programlisting><![CDATA[select foo.id, avg(name), max(name) 
+from Foo foo join foo.names name
+group by foo.id]]></programlisting>
+
+        <para>
+            Se permite tambi&#x00e9;n una cl&#x00e1;usula <literal>having</literal>.
+        </para>
+
+        <programlisting><![CDATA[select cat.color, sum(cat.weight), count(cat) 
+from Cat cat
+group by cat.color 
+having cat.color in (eg.Color.TABBY, eg.Color.BLACK)]]></programlisting>
+
+        <para>
+            Las funciones y funciones de agregaci&#x00f3;n SQL est&#x00e1;n permitidas en las cl&#x00e1;usulas
+            <literal>having</literal> y <literal>order by</literal>, si est&#x00e1;n soportadas por la base de datos
+            subyacente (por ejemplo, no en MySQL).
+        </para>
+
+        <programlisting><![CDATA[select cat
+from Cat cat
+    join cat.kittens kitten
+group by cat
+having avg(kitten.weight) > 100
+order by count(kitten) asc, sum(kitten.weight) desc]]></programlisting>
+
+        <para>
+            Nota que ni la cl&#x00e1;usula <literal>group by</literal> ni la cl&#x00e1;usula <literal>order by</literal> pueden
+            contener expresiones aritm&#x00e9;ticas.
+        </para>
+
+    </sect1>
+    
+    <sect1 id="queryhql-subqueries">
+        <title>Subconsultas</title>
+        
+        <para>
+            Para bases de datos que soportan subconsultas, Hibernate soporta subconsultas dentro de consultas. Una
+            subconsulta debe ser encerrada entre par&#x00e9;ntesis (frecuentemente por una llamada a una funci&#x00f3;n de agregaci&#x00f3;n
+            SQL). Incluso se permiten subconsultas correlacionadas (subconsultas que hacen referencia a un alias en la
+            consulta exterior).
+        </para>
+
+        <programlisting><![CDATA[from Cat as fatcat 
+where fatcat.weight > ( 
+    select avg(cat.weight) from DomesticCat cat 
+)]]></programlisting>
+
+        <programlisting><![CDATA[from DomesticCat as cat 
+where cat.name = some ( 
+    select name.nickName from Name as name 
+)]]></programlisting>
+    
+        <programlisting><![CDATA[from Cat as cat 
+where not exists ( 
+    from Cat as mate where mate.mate = cat 
+)]]></programlisting>
+
+        <programlisting><![CDATA[from DomesticCat as cat 
+where cat.name not in ( 
+    select name.nickName from Name as name 
+)]]></programlisting>
+
+        <para>
+            Para las subconsultas con m&#x00e1;s de una expresi&#x00f3;n en la lista de selecci&#x00f3;n, puedes usar un constructor
+            de tuplas:
+        </para>
+        
+        <programlisting><![CDATA[from Cat as cat 
+where not ( cat.name, cat.color ) in ( 
+    select cat.name, cat.color from DomesticCat cat 
+)]]></programlisting>
+
+        <para>
+            Nota que en algunas bases de datos (pero no en Oracle o HSQL), puedes usar constructores de tuplar en
+            otros contextos, por ejemplo al consultar componentes o tipos de usuario compuestos:
+        </para>
+
+        <programlisting><![CDATA[from Person where name = ('Gavin', 'A', 'King')]]></programlisting>
+        
+        <para>
+            Que es equivalente a la m&#x00e1;s verborr&#x00e1;gica:
+        </para>
+        
+        <programlisting><![CDATA[from Person where name.first = 'Gavin' and name.initial = 'A' and name.last = 'King')]]></programlisting>
+
+        <para>
+            Existen dos buenas razones por las cuales podr&#x00ed;as no querer hacer este tipo de cosa: primero, no es
+            completamente portable entre plataformas de base de datos; segundo, la consulta ahora es dependiente
+            del orden de propiedades en el documento de mapeo.
+        </para>
+        
+    </sect1>
+
+    <sect1 id="queryhql-examples">
+        <title>Ejemplos de HQL</title>
+        
+        <para>
+            Las consultas de Hibernate pueden ser abolutamente potentes y complejas, De hecho, el poder del lenguaje
+            de consulta es uno de los puntos principales de venta de Hibernate. He aqu&#x00ed; algunos consultas de ejemplo
+            muy similares a consultas que he usado en un proyecto reciente. &#x00a1;Nota que la mayor&#x00ed;a de las consultas
+            que escribir&#x00e1;s som mucho m&#x00e1;s simples que estas!
+        </para>
+        
+        <para>
+            La siguiente consulta devuelve el order id, n&#x00fa;mero de items y valor total de la orden para todas
+            las ordenes inpagas de un cliente en particular y valor total m&#x00ed;nimo dados, ordenando los resultados
+            por valor total. Al determinar los precios, usa el cat&#x00e1;logo actual. La consulta SQL resultante,
+            contra las tablas <literal>ORDER</literal>, <literal>ORDER_LINE</literal>, <literal>PRODUCT</literal>,
+            <literal>CATALOG</literal> and <literal>PRICE</literal> tiene cuatro joins interiores y una subselect
+            (no correlacionada).
+        </para>
+        
+        <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+    join order.lineItems as item
+    join item.product as product,
+    Catalog as catalog
+    join catalog.prices as price
+where order.paid = false
+    and order.customer = :customer
+    and price.product = product
+    and catalog.effectiveDate < sysdate
+    and catalog.effectiveDate >= all (
+        select cat.effectiveDate 
+        from Catalog as cat
+        where cat.effectiveDate < sysdate
+    )
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+        
+        <para>
+            &#x00a1;Qu&#x00e9; monstruo! Realmente, en la vida real, no estoy muy afilado en subconsultas, de modo que mi
+            consulta fue realmente algo como esto:
+        </para>
+        
+        <programlisting><![CDATA[select order.id, sum(price.amount), count(item)
+from Order as order
+    join order.lineItems as item
+    join item.product as product,
+    Catalog as catalog
+    join catalog.prices as price
+where order.paid = false
+    and order.customer = :customer
+    and price.product = product
+    and catalog = :currentCatalog
+group by order
+having sum(price.amount) > :minAmount
+order by sum(price.amount) desc]]></programlisting>
+        
+        <para>
+            La pr&#x00f3;xima consulta cuenta el n&#x00fa;mero de pagos en cada estado, excluyendo todos los pagos
+            en el estado <literal>AWAITING_APPROVAL</literal> donde el estado m&#x00e1;s reciente fue hecho por el
+            usuario actual. Se traduce en una consulta SQL con dos joins interiores y una subselect
+            correlacionada contra las tablas <literal>PAYMENT</literal>, <literal>PAYMENT_STATUS</literal> y
+            <literal>PAYMENT_STATUS_CHANGE</literal>.
+        </para>
+
+        <programlisting><![CDATA[select count(payment), status.name 
+from Payment as payment 
+    join payment.currentStatus as status
+    join payment.statusChanges as statusChange
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+    or (
+        statusChange.timeStamp = ( 
+            select max(change.timeStamp) 
+            from PaymentStatusChange change 
+            where change.payment = payment
+        )
+        and statusChange.user <> :currentUser
+    )
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+        <para>
+            Si hubiese mapeado la colecci&#x00f3;n <literal>statusChanges</literal> como una lista, en vez de un conjunto,
+            la consulta habr&#x00ed;a sido mucho m&#x00e1;s simple de escribir.
+        </para>
+    
+        <programlisting><![CDATA[select count(payment), status.name 
+from Payment as payment
+    join payment.currentStatus as status
+where payment.status.name <> PaymentStatus.AWAITING_APPROVAL
+    or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <> :currentUser
+group by status.name, status.sortOrder
+order by status.sortOrder]]></programlisting>
+
+        <para>
+            La pr&#x00f3;xima consulta usa la funci&#x00f3;n <literal>isNull()</literal> de MS SQL Server para devolver
+            todas las cuentas y pagos inpagos de la organizaci&#x00f3;n a la que pertenece el usuario actual.
+            Se traduce en una consulta SQL con tres joins interiores, un join exterior y una subconsulta
+            contra las tablas <literal>ACCOUNT</literal>, <literal>PAYMENT</literal>, <literal>PAYMENT_STATUS</literal>,
+            <literal>ACCOUNT_TYPE</literal>, <literal>ORGANIZATION</literal> y <literal>ORG_USER</literal>.
+        </para>
+
+        <programlisting><![CDATA[select account, payment
+from Account as account
+    left outer join account.payments as payment
+where :currentUser in elements(account.holder.users)
+    and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+        <para> 
+            Para algunas bases de datos, necesitar&#x00ed;amos eliminar la subselect (correlacionada).
+        </para>
+
+        <programlisting><![CDATA[select account, payment
+from Account as account
+    join account.holder.users as user
+    left outer join account.payments as payment
+where :currentUser = user
+    and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
+order by account.type.sortOrder, account.accountNumber, payment.dueDate]]></programlisting>
+
+   </sect1>
+
+    <sect1 id="queryhql-bulk">
+        <title>Sentencias UPDATE y DELETE masivas</title>
+
+        <para>
+            HQL soporta ahora sentencias UPDATE y DELETE en HQL.
+            Ver <xref linkend="batch-direct"/> para detalles.
+        </para>
+    </sect1>
+
+    <sect1 id="queryhql-tipstricks">
+        <title>Consejos y Trucos</title>
+
+        <para>
+            Puedes contar el n&#x00fa;mero de resultados de una consulta sin devolverlos realmente:
+        </para>
+
+        <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()]]></programlisting>
+
+        <para>
+            Para ordenar un resultado por el tama&#x00f1;o de una colecci&#x00f3;n, usa la siguiente consulta:
+        </para>
+
+        <programlisting><![CDATA[select usr.id, usr.name
+from User as usr 
+    left join usr.messages as msg
+group by usr.id, usr.name
+order by count(msg)]]></programlisting>
+
+        <para>
+            Si tu base de datos soporta subselects, puedes colocar una condici&#x00f3;n sobre el tama&#x00f1;o de selecci&#x00f3;n
+            en la cl&#x00e1;usula where de tu consulta:
+        </para>
+
+        <programlisting><![CDATA[from User usr where size(usr.messages) >= 1]]></programlisting>
+
+        <para>
+            Si tu base de datos no soporta subselects, usa la siguiente consulta:
+        </para>
+
+        <programlisting><![CDATA[select usr.id, usr.name
+from User usr.name
+    join usr.messages msg
+group by usr.id, usr.name
+having count(msg) >= 1]]></programlisting>
+
+        <para>
+            Como esta soluci&#x00f3;n no puede devolver un <literal>User</literal> con cero mensajes debido a la uni&#x00f3;n interior,
+            la siguiente forma es tambi&#x00e9;n &#x00fa;til:
+        </para>
+
+        <programlisting><![CDATA[select usr.id, usr.name
+from User as usr
+    left join usr.messages as msg
+group by usr.id, usr.name
+having count(msg) = 0]]></programlisting>
+
+        <para>
+            Las propiedades de un JavaBean pueden ser ligadas al par&#x00e1;metros de consulta con nombre:
+        </para>
+
+        <programlisting><![CDATA[Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");
+q.setProperties(fooBean); // fooBean has getName() and getSize()
+List foos = q.list();]]></programlisting>
+
+        <para>
+            Las colecciones son paginables usando la interface <literal>Query</literal> con un filtro:
+        </para>
+
+        <programlisting><![CDATA[Query q = s.createFilter( collection, "" ); // the trivial filter
+q.setMaxResults(PAGE_SIZE);
+q.setFirstResult(PAGE_SIZE * pageNumber);
+List page = q.list();]]></programlisting>
+
+        <para>
+            Los elementos de colecci&#x00f3;n pueden ser ordenados o agrupados usando un filtro de consulta:
+        </para>
+        
+        <programlisting><![CDATA[Collection orderedCollection = s.filter( collection, "order by this.amount" );
+Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );]]></programlisting>
+
+        <para>
+            Puedes hallar el tama&#x00f1;o de una colecci&#x00f3;n sin inicializarla:
+        </para>
+
+        <programlisting><![CDATA[( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue();]]></programlisting>
+
+    </sect1>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_sql.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/query_sql.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_sql.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/query_sql.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,477 @@
+<chapter id="querysql" revision="2">
+    <title>SQL Nativo</title>
+
+    <para>
+        Puedes tambi&#x00e9;n expresar consultas en el dialecto SQL nativo de tu base de datos. Esto es &#x00fa;til si quieres
+        utilizar aspectos espec&#x00ed;ficos de base de datos tal como consejos (hints) de consulta o la palabra clave
+        <literal>CONNECT</literal> en Oracle. Provee adem&#x00e1;s una clara ruta de migraci&#x00f3;n desde una aplicaci&#x00f3;n
+        basada en SQL/JDBC directo a Hibernate.
+    </para>
+
+    <para>
+        Hibernate3 te permite especificar SQL escrito a mano (incluyendo procedimientos almacenados) para todas
+        las operaciones de creaci&#x00f3;n, actualizaci&#x00f3;n, borrado y carga.
+    </para>
+
+    <sect1 id="querysql-creating">
+        <title>Creando una <literal>Query</literal> de SQL nativo</title>
+
+        <para>
+            Las consultas SQL se controlan por medio de la interface <literal>SQLQuery</literal>, que se obtiene
+            llamando a <literal>Session.createSQLQuery()</literal>.
+        </para>
+
+        <programlisting><![CDATA[List cats = sess.createSQLQuery("select {cat.*} from cats cat")
+    .addEntity("cat", Cat.class)
+    .setMaxResults(50)
+    .list();]]></programlisting>
+
+        <para>
+            Esta consulta especificada:
+        </para>
+
+        <itemizedlist>
+        <listitem>
+        <para>
+            la cadena de consulta SQL, con un lugar para que Hibernate inyecte los alias de columnas
+        </para>
+        </listitem>
+        <listitem>
+        <para>
+            la entidad devuelta por la consulta, y sus alias de tablas SQL
+        </para>
+        </listitem>
+        </itemizedlist>
+    
+        <para>
+            El m&#x00e9;todo <literal>addEntity()</literal> asocia alias de tablas SQL con clases de entidad,
+            y determina la forma del conjunto resultado de la consulta.
+        </para>
+        
+        <para>
+            El m&#x00e9;todo <literal>addJoin()</literal> puede ser usado para cargar asociaciones a otras entidades y
+            colecciones.
+        </para>
+        
+        <programlisting><![CDATA[List cats = sess.createSQLQuery(
+        "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id"
+    )
+    .addEntity("cat", Cat.class)
+    .addJoin("kitten", "cat.kittens")
+    .list();]]></programlisting>
+    
+        <para>
+            Una consulta SQL nativa podr&#x00ed;a devolver un valor escalar simple o una combinaci&#x00f3;n de escalares y entidades.
+        </para>
+
+        <programlisting><![CDATA[Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat")
+        .addScalar("maxWeight", Hibernate.DOUBLE);
+        .uniqueResult();]]></programlisting>
+
+
+    </sect1>
+
+    <sect1 id="querysql-aliasreferences">
+        <title>Alias y referencias de propiedad</title>
+
+        <para>
+            La notaci&#x00f3;n <literal>{cat.*}</literal> usada arriba es un atajo para "todas las propiedades".
+            Alternativamente, puedes listar las columnas expl&#x00ed;citamente, pero incluso en este caso dejamos
+            que Hibernate inyecte los alias de columnas SQL para cada propiedad. El lugar para un alias de columna
+            es s&#x00f3;lo el nombre de propiedad cualificado por el alias de la tabla. En el siguiente ejemplo,
+            recuperamos <literal>Cat</literal>s de una tabla diferente (<literal>cat_log</literal>) a una
+            declarada en los metadatos de mapeo. Nota que podr&#x00ed;amos incluso usar los alias de propiedad en la
+            cl&#x00e1;usula where si quisieramos.
+        </para>
+        <para>
+            La sint&#x00e1;xis <literal>{}</literal> <emphasis>no</emphasis> es requerida para consultas con nombre.
+            Ver <xref linkend="querysql-namedqueries"/>
+        </para>
+
+        <programlisting><![CDATA[String sql = "select cat.originalId as {cat.id}, " +
+    "cat.mateid as {cat.mate}, cat.sex as {cat.sex}, " +
+    "cat.weight*10 as {cat.weight}, cat.name as {cat.name} " +
+    "from cat_log cat where {cat.mate} = :catId"
+    
+List loggedCats = sess.createSQLQuery(sql)
+    .addEntity("cat", Cat.class)
+    .setLong("catId", catId)
+    .list();]]></programlisting>
+
+        <para>
+            <emphasis>Nota:</emphasis> si listas cada propiedad expl&#x00ed;citamente, &#x00a1;debes incluir todas las
+            propiedades de la clase <emphasis>y sus subclases</emphasis>!
+        </para>
+
+    </sect1>
+    
+    <sect1 id="querysql-namedqueries" revision="2">
+        <title>Consultas SQL con nombre</title>
+
+        <para>
+            Las consultas SQL con nombre pueden definirse en el documento de mapeo y llamadas exactamente
+            en la misma forma en que a una consulta HQL con nombre. En este caso, <emphasis>no</emphasis>
+            necesitamos llamar a <literal>addEntity()</literal>.
+        </para>
+
+         <programlisting><![CDATA[<sql-query name="persons">
+    <return alias="person" class="eg.Person"/>
+    SELECT person.NAME AS {person.name},
+           person.AGE AS {person.age},
+           person.SEX AS {person.sex}
+    FROM PERSON person 
+    WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+        <programlisting><![CDATA[List people = sess.getNamedQuery("persons")
+    .setString("namePattern", namePattern)
+    .setMaxResults(50)
+    .list();]]></programlisting>
+
+         <para>
+             Los elementos <literal>&lt;return-join&gt;</literal> y <literal>&lt;load-collection&gt;</literal>
+             se usan para unir asociaciones y definir consultas que inicialicen colecciones, respectivamente.
+         </para>
+         
+         <programlisting><![CDATA[<sql-query name="personsWith">
+    <return alias="person" class="eg.Person"/>
+    <return-join alias="address" property="person.mailingAddress"/>
+    SELECT person.NAME AS {person.name},
+           person.AGE AS {person.age},
+           person.SEX AS {person.sex},
+           address.STREET AS {address.street},
+           address.CITY AS {address.city},
+           address.STATE AS {address.state},
+           address.ZIP AS {address.zip}
+    FROM PERSON person 
+    JOIN ADDRESS address
+    	ON person.ID = address.PERSON_ID AND address.TYPE='MAILING'
+    WHERE person.NAME LIKE :namePattern
+</sql-query>]]></programlisting>
+
+        <para>
+            Una consulta SQL con nombre puede devolver un valor escalar. Debes especificar el alias de columna y
+            tipo Hibernate usando el elementp <literal>&lt;return-scalar&gt;</literal>:
+        </para>
+        
+        <programlisting><![CDATA[<sql-query name="mySqlQuery">
+    <return-scalar column="name" type="string"/>
+    <return-scalar column="age" type="long"/>
+    SELECT p.NAME AS name,
+           p.AGE AS age,
+    FROM PERSON p WHERE p.NAME LIKE 'Hiber%'
+</sql-query>]]></programlisting>
+
+         <sect2 id="propertyresults">
+             <title>Usando return-property para especificar expl&#x00ed;citamente nombres de columna/alias</title>
+             
+             <para>
+                 Con <literal>&lt;return-property&gt;</literal> puedes decirle expl&#x00ed;citamente a Hibernate qu&#x00e9;
+                 alias de columna usar, en vez de usar la sint&#x00e1;xis <literal>{}</literal> para dejar que Hibernate
+                 inyecte sus propios alias.
+             </para>
+             
+            <programlisting><![CDATA[<sql-query name="mySqlQuery">
+    <return alias="person" class="eg.Person">
+        <return-property name="name" column="myName"/>
+        <return-property name="age" column="myAge"/>
+        <return-property name="sex" column="mySex"/>
+    </return>
+    SELECT person.NAME AS myName,
+           person.AGE AS myAge,
+           person.SEX AS mySex,
+    FROM PERSON person WHERE person.NAME LIKE :name
+</sql-query>
+]]></programlisting>
+             
+             <para>
+                 <literal>&lt;return-property&gt;</literal> tambi&#x00e9;n trabaja con m&#x00fa;ltiples columnas. Esto resuelve una
+                 limitaci&#x00f3;n de la sint&#x00e1;xis <literal>{}</literal>, la cual no puede permitir un control fino de propiedades
+                 multi-columna.
+             </para>
+             
+             <programlisting><![CDATA[<sql-query name="organizationCurrentEmployments">
+    <return alias="emp" class="Employment">            
+        <return-property name="salary"> 
+            <return-column name="VALUE"/>
+            <return-column name="CURRENCY"/>            
+        </return-property>
+        <return-property name="endDate" column="myEndDate"/>
+    </return>
+        SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer}, 
+        STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},
+        REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCY
+        FROM EMPLOYMENT
+        WHERE EMPLOYER = :id AND ENDDATE IS NULL
+        ORDER BY STARTDATE ASC
+</sql-query>]]></programlisting>
+             
+            <para>
+                Nota que en este ejemplo hemos usado <literal>&lt;return-property&gt;</literal> en combinaci&#x00f3;n con
+                la sint&#x00e1;xis <literal>{}</literal> para inyecci&#x00f3;n, permitiendo a los usuarios elejir c&#x00f3;mo quieren
+                referirse a las columnas y propiedades.
+            </para>
+
+            <para>
+                Si tu mapeo tiene un discriminador debes usar <literal>&lt;return-discriminator&gt;</literal>
+                para especificar la columna discriminadora.
+            </para>
+         </sect2>
+         
+         <sect2 id="sp_query">
+             <title>Usando procedimientos almacenados para consultar</title>
+             
+             <para>
+                 Hibernate3 introduce soporte para consultas v&#x00ed;a procedimientos almacenados. Los procedimientos
+                 almacenados deben devolver un conjunto resultado como el primer par&#x00e1;metro de salida para ser
+                 capaces de funcionar con Hibernate. Un ejemplo de uno procedimiento almacenado en Oracle 9
+                 o superior es as&#x00ed;:
+             </para>
+                 
+                 <programlisting><![CDATA[CREATE OR REPLACE FUNCTION selectAllEmployments 
+    RETURN SYS_REFCURSOR 
+AS 
+    st_cursor SYS_REFCURSOR; 
+BEGIN 
+    OPEN st_cursor FOR 
+ SELECT EMPLOYEE, EMPLOYER, 
+ STARTDATE, ENDDATE, 
+ REGIONCODE, EID, VALUE, CURRENCY 
+ FROM EMPLOYMENT; 
+      RETURN  st_cursor; 
+ END;]]></programlisting>
+                 
+             <para>
+                 Para usar esta consulta en Hibernate necesitas mapearla por medio de una consulta con nombre.
+             </para>
+                 
+             <programlisting><![CDATA[<sql-query name="selectAllEmployees_SP" callable="true">
+    <return alias="emp" class="Employment">
+        <return-property name="employee" column="EMPLOYEE"/>
+        <return-property name="employer" column="EMPLOYER"/>            
+        <return-property name="startDate" column="STARTDATE"/>
+        <return-property name="endDate" column="ENDDATE"/>            
+        <return-property name="regionCode" column="REGIONCODE"/>            
+        <return-property name="id" column="EID"/>                        
+        <return-property name="salary"> 
+            <return-column name="VALUE"/>
+            <return-column name="CURRENCY"/>            
+        </return-property>
+    </return>
+    { ? = call selectAllEmployments() }
+</sql-query>]]></programlisting>
+             
+             <para>
+               Nota que los procedimientos almacenados s&#x00f3;lo devuelven escalares y entidades.
+               No est&#x00e1;n soportados <literal>&lt;return-join&gt;</literal> y <literal>&lt;load-collection&gt;</literal>.
+             </para>
+             
+             <sect3 id="querysql-limits-storedprocedures">
+               <title>Reglas/limitaciones para usar procedimientos almacenados</title>
+               
+               <para>
+                   Para usar procedimientos almacenados con Hibernate los procedimientos tienen que seguir algunas reglas.
+                   Si no siguen esas reglas no son usables por Hibernate. Si a&#x00fa;n quisieras usar estos procedimientos
+                   tendr&#x00ed;as que ejecutarlos por medio de <literal>session.connection()</literal>. Las reglas son
+                   diferentes para cada base de datos, ya que los vendedores de base de datos tienen diferentes
+                   sem&#x00e1;nticas/sint&#x00e1;xis de procedimientos almacenados.
+               </para>
+
+                <para>
+                   Las consultas de procedimientos almacenados no pueden ser paginadas con 
+                   <literal>setFirstResult()/setMaxResults()</literal>.
+               </para>
+
+                 <para>
+                   Para Oracle se aplican las siguientes reglas:
+               </para>
+               
+               <itemizedlist spacing="compact">
+               <listitem>
+               <para>    
+                   El procedimiento debe devolver un conjunto resultado. Esto se hace devolviendo un
+                   <literal>SYS_REFCURSOR</literal> en Oracle 9 o 10. En Oracle necesitas definir un
+                   tipo <literal>REF CURSOR</literal>.
+               </para>
+               </listitem>    
+               <listitem>
+               <para>
+                   La forma recomendada es <literal>{ ? = call procName(&lt;parameters&gt;) }</literal> o
+                   <literal>{ ? = call procName }</literal> (esto es m&#x00e1;s una regla de Oracle que una regla de Hibernate).
+               </para>
+               </listitem>    
+              </itemizedlist>
+                           
+              <para>                   
+                   Para Sybase o MS SQL server se aplican las siguientes reglas:
+               </para>
+                   
+               <itemizedlist spacing="compact">
+               <listitem>
+               <para>    
+                   El procedimiento debe devolver un conjunto resultado. Nota que ya que estos servidores pueden
+                   y devolver&#x00e1;n m&#x00fa;ltiples conjuntos resultados y cuentas de actualizaci&#x00f3;n, Hibernate iterar&#x00e1;
+                   los resultados y tomar&#x00e1; el primer resultado que sea un conjunto resultado como su valor
+                   a devolver. Todo lo dem&#x00e1;s ser&#x00e1; descartado.
+               </para>
+               </listitem>    
+               <listitem>
+               <para>
+                   Si habilitas <literal>SET NOCOUNT ON</literal> en tu procedimiento ser&#x00e1; probablemente m&#x00e1;s
+                   eficiente, pero esto no es un requerimiento.
+               </para>
+               </listitem>    
+              </itemizedlist>
+              </sect3>
+         </sect2>
+
+    </sect1>
+
+    <sect1 id="querysql-cud">
+        <title>SQL personalizado para crear, actualizar y borrar</title>
+
+        <para>
+            Hibernate3 puede usar sentencias SQL personalizadas para las operaciones de
+            crear, actualizar y borrar. Los persistidores de clases y colecciones en Hibernate
+            ya contienen un conjunto de cadenas generadas en tiempo de configuraci&#x00f3;n (insertsql,
+            deletesql, updatesql, etc.). Las etiquetas de mapeo <literal>&lt;sql-insert&gt;</literal>,
+            <literal>&lt;sql-delete&gt;</literal>, y <literal>&lt;sql-update&gt;</literal> sobrescriben
+            estas cadenas:
+        </para>
+
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id">
+        <generator class="increment"/>
+    </id>
+    <property name="name" not-null="true"/>
+    <sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert>
+    <sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update>
+    <sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
+</class>]]></programlisting>
+
+        <para>
+            El SQL se ejecuta directamente en tu base de datos, de modo que eres libre de usar cualquier
+            dialecto que quieras. Esto reducir&#x00e1;, por supuesto, la portabilidad de tu mapeo si usas SQL
+            espec&#x00ed;fico de la base de datos.
+        </para>
+
+        <para>
+            Los procedimientos almacenados son soportados si est&#x00e1; establecido el atributo
+            <literal>callable</literal>:
+        </para>
+
+    <programlisting><![CDATA[<class name="Person">
+    <id name="id">
+        <generator class="increment"/>
+    </id>
+    <property name="name" not-null="true"/>
+    <sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>
+    <sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
+    <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>
+</class>]]></programlisting>
+
+        <para>
+          El orden de los par&#x00e1;metros posicionales son actualmente vitales, ya que deben estar en la
+          misma secuencia en que las espera Hibernate.
+        </para>
+        
+        <para>
+          Puedes ver el orden esperado habilitando el registro de depuraci&#x00f3;n para el nivel
+          <literal>org.hibernate.persister.entity</literal>. Con este nivel habilitado, Hibernate
+          imprimir&#x00e1; el SQL est&#x00e1;tico que se usa para crear, actualizar, borrar, etc. las entidades.
+          (Para ver la secuencia esperada, recuerda no incluir tu SQL personalizado en los ficheros
+          de mapeo ya que sobrescribir&#x00e1;n el sql est&#x00e1;tico generado por Hibernate.)
+        </para>
+
+        <para>
+            Los procedimientos almacenados son, en la mayor&#x00ed;a de los casos (l&#x00e9;ase, mejor hacerlo que no hacerlo),
+            obligados a devolver el n&#x00fa;mero de filas insertadas/actualizadas/borradas, ya que Hibernate tiene algunas
+            comprobaciones en tiempo de ejecuci&#x00f3;n del &#x00e9;xito de la sentencia. Hibernate siempre registra el primer
+            par&#x00e1;metro de la sentencia como un par&#x00e1;metro de salida num&#x00e9;rico para las operaciones CUD:
+        </para>
+
+        <programlisting><![CDATA[CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)
+    RETURN NUMBER IS
+BEGIN
+
+    update PERSON
+    set
+        NAME = uname,
+    where
+        ID = uid;
+
+    return SQL%ROWCOUNT;
+
+END updatePerson;]]></programlisting>
+
+        
+    </sect1>
+
+    <sect1 id="querysql-load">
+        <title>SQL personalizado para carga</title>
+
+        <para>
+            Puedes tambi&#x00e9;n declarar tu propias consultas SQL (o HQL) para cargar entidades:
+        </para>
+
+        <programlisting><![CDATA[<sql-query name="person">
+    <return alias="pers" class="Person" lock-mode="upgrade"/>
+    SELECT NAME AS {pers.name}, ID AS {pers.id} 
+    FROM PERSON 
+    WHERE ID=? 
+    FOR UPDATE
+</sql-query>]]></programlisting>
+
+        <para>
+            Esto es s&#x00f3;lo una declaraci&#x00f3;n de consulta con nombrem como se ha discutido anteriormente.
+            Puedes hacer referencia a esta consulta con nombre en un mapeo de clase:
+        </para>
+
+        <programlisting><![CDATA[<class name="Person">
+    <id name="id">
+        <generator class="increment"/>
+    </id>
+    <property name="name" not-null="true"/>
+    <loader query-ref="person"/>
+</class>]]></programlisting>
+    
+        <para>
+            Esto incluso funciona con procedimientos almacenados.
+        </para>
+
+        <para>
+            Puedes incluso definit una consulta para la carga de colecciones:
+        </para>
+
+<programlisting><![CDATA[<set name="employments" inverse="true">
+    <key/>
+    <one-to-many class="Employment"/>
+    <loader query-ref="employments"/>
+</set>]]></programlisting>
+		
+        <programlisting><![CDATA[<sql-query name="employments">
+    <load-collection alias="emp" role="Person.employments"/>
+    SELECT {emp.*}
+    FROM EMPLOYMENT emp
+    WHERE EMPLOYER = :id
+    ORDER BY STARTDATE ASC, EMPLOYEE ASC
+</sql-query>]]></programlisting>
+
+        <para>
+            Podr&#x00ed;as incluso definir un cargador de entidades que cargue una colecci&#x00f3;n por
+            recuperaci&#x00f3;n por uni&#x00f3;n (join fetching):
+        </para>
+
+        <programlisting><![CDATA[<sql-query name="person">
+    <return alias="pers" class="Person"/>
+    <return-join alias="emp" property="pers.employments"/> 
+    SELECT NAME AS {pers.*}, {emp.*}
+    FROM PERSON pers
+    LEFT OUTER JOIN EMPLOYMENT emp 
+        ON pers.ID = emp.PERSON_ID
+    WHERE ID=?
+</sql-query>]]></programlisting>
+
+    </sect1>
+
+</chapter>
\ No newline at end of file

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/quickstart.xml (from rev 12891, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/quickstart.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/quickstart.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/quickstart.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,666 @@
+<chapter id="quickstart">
+    <title>Comienzo r&#x00e1;pido con Tomcat</title>
+
+    <sect1 id="quickstart-intro" revision="2">
+        <title>Empezando con Hibernate</title>
+
+        <para>
+            Este tutorial explica una instalaci&#x00f3;n de Hibernate con el
+            contenedor de servlets Apache Tomcat (hemos usado la versi&#x00f3;n 4.1,
+            las diferencias con la 5.0 deben ser m&#x00ed;nimas) para una aplicaci&#x00f3;n
+            basada en web. Hibernate trabaja bien en un entorno manejado con
+            todos los servidores de aplicaciones J2EE importantes, o incluso en aplicaciones
+            Java independientes. El sistema de base de datos es s&#x00f3;lo una cuesti&#x00f3;n
+            de cambiar la configuraci&#x00f3;n del dialecto SQL de Hibernate y las
+            propiedades de conexi&#x00f3;n.
+        </para>
+
+        <para>
+            Primero, tenemos que copiar todas las bibliotecas requeridas a la instalaci&#x00f3;n
+            de Tomcat. Usamos un contexto web separado (<literal>webapps/quickstart</literal>) 
+            para este tutorial, de modo que tenemos que considerar tanto la ruta de b&#x00fa;squeda
+            de bibliotecas global (<literal>TOMCAT/common/lib</literal>) como tambi&#x00e9;n
+            el cargador de clases a nivel de contexto en <literal>webapps/quickstart/WEB-INF/lib</literal>
+            (para ficheros JAR) y <literal>webapps/quickstart/WEB-INF/classes</literal>.
+            Nos referiremos a ambos niveles de cargador de clases como el classpath global y el classpath
+            de contexto, respectivamente.
+        </para>
+
+        <para>
+            Ahora, copia las bibliotecas a los dos classpaths:
+        </para>
+
+        <orderedlist>
+            <listitem>
+                <para>
+                    Copia el driver JDBC para la base de datos al classpath global. Esto se
+                    requiere para el software de pool de conexiones DBCP que se distribuye
+                    con Tomcat. Hibernate usa conexiones JDBC para ejecutar SQL sobre la base de
+                    datos, de modo que, o bien tienes que proveer conexiones JDBC en pool,
+                    o bien configurar Hibernate para que use uno de los pools soportados
+                    directamente (C3P0, Proxool). Para este tutorial, copia la biblioteca
+                    <literal>pg74jdbc3.jar</literal> (para PostgreSQL 7.4 y JDK 1.4) al
+                    classpath del cargador global. Si quisieras usar una base de datos diferente,
+                    simplemente copia su apropiado driver JDBC.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Nunca copies nada m&#x00e1;s dentro de la ruta del cargador de clases global
+                    en Tomcat, o tendr&#x00e1;s problemas con varias herramientas, incluyendo
+                    Log4J, commons-logging y otras. Siempre usa el classpath de contexto para
+                    cada aplicaci&#x00f3;n web, esto es, copia las bibliotecas a
+                    <literal>WEB-INF/lib</literal> y tus propias clases y ficheros de
+                    configuraci&#x00f3;n/propiedades a <literal>WEB-INF/classes</literal>.
+                    Ambos directorios est&#x00e1;n a nivel del classpath de contexto por defecto.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Hibernate est&#x00e1; empaquetado como una biblioteca JAR. El fichero
+                    <literal>hibernate3.jar</literal> debe ser copiado en el classpath de contexto
+                    junto a las otras clases de la aplicaci&#x00f3;n. Hibernate requiere algunas
+                    bibliotecas de terceros en tiempo de ejecuci&#x00f3;n; &#x00e9;stas vienen
+                    inclu&#x00ed;das con la distribuci&#x00f3;n de Hibernate en el directorio
+                    <literal>lib/</literal>. Ver <xref linkend="3rdpartylibs"/>. Copia las
+                    bibliotecas de terceros requeridas al classpath de contexto.
+                </para>
+            </listitem>
+        </orderedlist>
+
+        <table frame="topbot" id="3rdpartylibs">
+            <title>
+                Bibliotecas de terceros de Hibernate
+            </title>
+            <tgroup cols="2" rowsep="1" colsep="1">
+                <colspec colname="c1" colwidth="1*"/>
+                <colspec colname="c2" colwidth="2*"/>
+                <thead>
+                    <row>
+                        <entry align="center">
+                            Biblioteca
+                        </entry>
+                        <entry align="center">
+                            Descripci&#x00f3;n
+                        </entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>
+                            antlr (requerida)
+                        </entry>
+                        <entry>
+                            Hibernate usa ANTLR para producir analizadores de consultas,
+                            esta biblioteca tambi&#x00e9;n se necesita en tiempo de ejecuci&#x00f3;n.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            dom4j (requerida)
+                        </entry>
+                        <entry>
+                            Hibernate usa dom4j para analizar ficheros de configuraci&#x00f3;n
+                            XML y ficheros de metadatos de mapeo XML.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            CGLIB, asm (requerida)
+                        </entry>
+                        <entry>
+                            Hibernate usa la biblioteca de generaci&#x00f3;n de c&#x00f3;digo
+                            para aumentar las clases en tiempo de ejecuci&#x00f3;n
+                            (en combinaci&#x00f3;n con reflecci&#x00f3;n Java).
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            Commons Collections, Commons Logging (requeridas)
+                        </entry>
+                        <entry>
+                            Hibernate usa varias bibliotecas de utilidad del proyecto
+                            Jakarta Commons de Apache.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            EHCache (requerida)
+                        </entry>
+                        <entry>
+                            Hibernate puede usar varios provedores de cach&#x00e9; para
+                            el cach&#x00e9; de segundo nivel. EHCache es el provedor de
+                            cach&#x00e9; por defecto si no se cambia en la configuraci&#x00f3;n.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            Log4j (opcional)
+                        </entry>
+                        <entry>
+                            Hibernate usa la API de Commons Logging, que a su vez puede
+                            usar Log4J como el mecanismo de logging subyacente. Si la
+                            biblioteca Log4J est&#x00e1; disponible en el directorio de
+                            bibliotecas del contexto, Commons Logging usar&#x00e1; Log4J
+                            y la configuraci&#x00f3;n <literal>log4j.properties</literal>
+                            en el classpath de contexto. Un fichero de propiedades de ejemplo
+                            para Log4J se incluye con la distribuci&#x00f3;n de Hibernate.
+                            As&#x00ed; que copia log4j.jar y el fichero de configuraci&#x00f3;n
+                            (de <literal>src/</literal>) a tu classpath de contexto si quieres
+                            ver que ocurre tras esc&#x00e9;nas.
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>
+                            ¿Requerida o no?
+                        </entry>
+                        <entry>
+                            Echa una mirada al fichero <literal>lib/README.txt</literal> en la
+                            distribuci&#x00f3;n de Hibernate. Esta es una lista actualizada
+                            de bibliotecas de terceros distribu&#x00ed;das con Hibernate.
+                            Encontrar&#x00e1;s listadas ah&#x00ed; todas las bibliotecas
+                            requeridas y opcionales (Observa que "buildtame required" significa
+                            aqu&#x00ed; para la construcci&#x00f3;n de Hibernate, no de tu
+                            aplicaci&#x00f3;n).
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+
+        <para>
+            Ahora instalamos el pooling y modo compartido de conexiones de base de datos
+            tanto en Tomcat como Hibernate. Esto significa que Tomcat proveer&#x00e1;
+            conexiones JDBC en pool (usando su funcionalidad prefabricada de pooling DBCP).
+            Hibernate pide esas conexiones a trav&#x00e9;s de JNDI. Alternativamente,
+            puedes dejar que Hibernate maneje el pool de conexiones. Tomcat liga su pool
+            de conexiones a JNDI; agregamos una declaraci&#x00f3;n de recurso al fichero
+            de configuraci&#x00f3;n principal de Tomcat, <literal>TOMCAT/conf/server.xml</literal>:
+        </para>
+
+        <programlisting><![CDATA[<Context path="/quickstart" docBase="quickstart">
+    <Resource name="jdbc/quickstart" scope="Shareable" type="javax.sql.DataSource"/>
+    <ResourceParams name="jdbc/quickstart">
+        <parameter>
+            <name>factory</name>
+            <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+        </parameter>
+
+        <!-- DBCP database connection settings -->
+        <parameter>
+            <name>url</name>
+            <value>jdbc:postgresql://localhost/quickstart</value>
+        </parameter>
+        <parameter>
+            <name>driverClassName</name><value>org.postgresql.Driver</value>
+        </parameter>
+        <parameter>
+            <name>username</name>
+            <value>quickstart</value>
+        </parameter>
+        <parameter>
+            <name>password</name>
+            <value>secret</value>
+        </parameter>
+
+        <!-- DBCP connection pooling options -->
+        <parameter>
+            <name>maxWait</name>
+            <value>3000</value>
+        </parameter>
+        <parameter>
+            <name>maxIdle</name>
+            <value>100</value>
+        </parameter>
+        <parameter>
+            <name>maxActive</name>
+            <value>10</value>
+        </parameter>
+    </ResourceParams>
+</Context>]]></programlisting>
+
+        <para>
+            El contexto que configuramos en este ejemplo se llama <literal>quickstart</literal>,
+            su base es el directorio <literal>TOMCAT/webapp/quickstart</literal>. Para acceder
+            a cualquier servlet, llama a la ruta <literal>http://localhost:8080/quickstart</literal>
+            en tu navegador (por supuesto, agregando el nombre del servlet como se mapee en tu
+            <literal>web.xml</literal>). Puedes tambi&#x00e9;n ir m&#x00e1;s all&#x00e1; y crear
+            ahora un servlet simple que tenga un m&#x00e9;todo <literal>process()</literal>
+            vac&#x00ed;o.
+        </para>
+
+        <para>
+            Tomcat provee ahora conexiones a trav&#x00e9;s de JNDI en
+            <literal>java:comp/env/jdbc/quickstart</literal>. Si tienes problemas obteniendo
+            el pool de conexiones en ejecuci&#x00f3;n, refi&#x00e9;rete a la documentaci&#x00f3;n
+            de Tomcat. Si obtienes mensajes de excepci&#x00f3;n del driver JDBC, intenta instalar
+            primero el pool de conexiones JDBC sin Hibernate. Hay disponibles en la Web
+            tutoriales de Tomcat y JDBC.
+        </para>
+
+        <para>
+            Tu pr&#x00f3;ximo paso es configurar Hibernate. Hibernate tiene que saber c&#x00f3;mo
+            debe obtener conexiones JDBC. Usamos la configuraci&#x00f3;n de Hibernate basada en XML.
+            El otro enfoque, usando un ficheros de propiedad, es casi equivalente pero pierde unas
+            pocas funcionalidades que s&#x00ed; permite la sintaxis XML. El fichero de configuraci&#x00f3;n
+            XML se ubica en el classpath de contexto (<literal>WEB-INF/classes</literal>), como
+            <literal>hibernate.cfg.xml</literal>:
+        </para>
+
+        <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+    "-//Hibernate/Hibernate Configuration DTD//EN"
+    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+    <session-factory>
+
+        <property name="connection.datasource">java:comp/env/jdbc/quickstart</property>
+        <property name="show_sql">false</property>
+        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
+
+        <!-- Mapping files -->
+        <mapping resource="Cat.hbm.xml"/>
+
+    </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+        <para>
+            Desactivamos el registro (logging) de comandos SQL y decimos a Hibernate
+            qu&#x00e9; dialecto SQL de base de datos se usa y d&#x00f3;nde obtener
+            conexiones JDBC (declarando la direcci&#x00f3;n JNDI del pool ligado a
+            Tomcat). El dialecto es una configuraci&#x00f3;n requerida, las bases de
+            datos difieren en su interpretaci&#x00f3;n del "est&#x00e1;ndar" de SQL.
+            Hibernate cuidar&#x00e1; de las diferencias y viene con dialectos inclu&#x00ed;dos
+            para todas las principales bases de datos comerciales y de c&#x00f3;digo
+            abierto.
+        </para>
+
+        <para>
+            Una <literal>SessionFactory</literal> es el concepto de Hibernate
+            de un almac&#x00e9;n de datos solo. Pueden usarse m&#x00fa;ltiples
+            bases de datos creando m&#x00fa;ltiples ficheros de configuraci&#x00f3;n
+            XML y creando m&#x00fa;ltiples objetos <literal>Configuration</literal>
+            y <literal>SessionFactory</literal> en tu aplicaci&#x00f3;n.
+        </para>
+
+        <para>
+            El &#x00fa;ltimo elemento del <literal>hibernate.cfg.xml</literal>
+            declara <literal>Cat.hbm.xml</literal> como el nombre de un fichero
+            de mapeo XML para la clase persistente <literal>Cat</literal>. Este
+            fichero contiene los metadatos para el mapeo de la clase POJO 
+            <literal>Cat</literal> a una tabla (o tablas) de base de datos.
+            Volveremos a este fichero pronto. Escribamos primero la clase POJO
+            y luego declaremos los metadatos de mapeo para ella.
+        </para>
+
+    </sect1>
+
+    <sect1 id="quickstart-persistentclass" revision="1">
+        <title>Primera clase persistente</title>
+
+        <para>
+            Hibernate trabaja mejor con el modelo de programaci&#x00f3;n de los 
+            Viejos Objetos Planos de Java (POJOs, a veces llamados Ordinarios Objetos Planos de Java)
+            para clases persistentes. Un POJO es como un JavaBean, con las propiedades
+            de la clase accesible v&#x00ed;a m&#x00e9;todos getter y setter,
+            encapsulando la representaci&#x00f3;n interna de la interfaz publicamente
+            visible (Hibernate puede tambi&#x00e9;n acceder a los campos directamente, si se
+            necesita):
+        </para>
+
+        <programlisting><![CDATA[package org.hibernate.examples.quickstart;
+
+public class Cat {
+
+    private String id;
+    private String name;
+    private char sex;
+    private float weight;
+
+    public Cat() {
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    private void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public char getSex() {
+        return sex;
+    }
+
+    public void setSex(char sex) {
+        this.sex = sex;
+    }
+
+    public float getWeight() {
+        return weight;
+    }
+
+    public void setWeight(float weight) {
+        this.weight = weight;
+    }
+
+}]]></programlisting>
+
+        <para>
+            Hibernate no est&#x00e1; restringido en su uso de tipos de propiedad, todos
+            los tipos y tipos primitivos del JDK de Java (como <literal>String</literal>,
+            <literal>char</literal> y <literal>Date</literal>) pueden ser mapeados, incluyendo
+            clases del framework de colecciones de Java. Puedes mapearlos como valores,
+            colecciones de valores, o asociaciones a otras entidades. El <literal>id</literal>
+            es una propiedad especial que representa el identificador de base de datos (clave
+            primaria) de la clase. Es altamente recomendado para entidades como un
+            <literal>Cat</literal>. Hibernate puede usar identificadores s&#x00f3;lo
+            internamente, pero perder&#x00ed;amos algo de la flexibilidad en nuestra
+            arquitectura de aplicaci&#x00f3;n.
+        </para>
+
+        <para>
+            No tiene que implementarse ninguna interface especial para las clases persistentes
+            ni tienes que subclasear de una clase persistente ra&#x00ed;z en especial. Hibernate
+            tampoco requiere ning&#x00fa;n procesamiento en tiempo de construcci&#x00f3;n, 
+            como manipulaci&#x00f3;n del byte-code. Se basa solamente en reflecci&#x00f3;n de Java
+            y aumentaci&#x00f3;n de clases en tiempo de ejecuci&#x00f3;n (a trav&#x00e9;s de CGLIB).
+            De modo que, sin ninguna dependencia de la clase POJO en Hibernate, podemos mapearla
+            a una tabla de base de datos.
+        </para>
+
+    </sect1>
+
+    <sect1 id="quickstart-mapping" revision="1">
+        <title>Mapeando el gato</title>
+
+        <para>
+            El fichero de mapeo <literal>Cat.hbm.xml</literal> contiene los
+            metadatos requeridos para el mapeo objeto/relacional. Los metadatos
+            incluyen la declaraci&#x00f3;n de clases persistentes y el mapeo de
+            propiedades (a columnas y relaciones de claves for&#x00e1;neas a otras
+            entidades) a tablas de base de datos.
+        </para>
+
+        <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+
+    <class name="org.hibernate.examples.quickstart.Cat" table="CAT">
+
+        <!-- A 32 hex character is our surrogate key. It's automatically
+            generated by Hibernate with the UUID pattern. -->
+        <id name="id" type="string" unsaved-value="null" >
+            <column name="CAT_ID" sql-type="char(32)" not-null="true"/>
+            <generator class="uuid.hex"/>
+        </id>
+
+        <!-- A cat has to have a name, but it shouldn' be too long. -->
+        <property name="name">
+            <column name="NAME" length="16" not-null="true"/>
+        </property>
+
+        <property name="sex"/>
+
+        <property name="weight"/>
+
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+        <para>
+            Cada clase persistente debe tener un atributo identificador (realmente, 
+            s&#x00f3;lo las clases que representen entidades, no las clases dependientes
+            de tipo-valor, que son mapeadas como componentes de una entidad). Esta propiedad
+            es usada para distinguir los objetos persistentes: Dos gatos son iguales si
+            <literal>catA.getId().equals(catB.getId())</literal> es verdadero. Este concepto
+            se llama <emphasis>identidad de base de datos (database identity)</emphasis>.
+            Hibernate viene empaquetado con varios generadores de identificador para diferentes
+            escenarios (incluyendo generadores nativos para secuencias de base de datos, tablas
+            de identificadores alto/bajo, e identificadores asignados por aplicaci&#x00f3;n).
+            Usamos el generador UUID (recomendado s&#x00f3;lo para pruebas, pues deben
+            preferirse las claves enteras delegadas generadas por la base de datos) y
+            tambi&#x00e9;n especificamos la columna <literal>CAT_ID</literal> de la tabla
+            <literal>CAT</literal> para el valor identificador generado por Hibernate
+            (como una clave primaria de la tabla).
+        </para>
+
+        <para>
+            Todas las dem&#x00e1;s propiedades de <literal>Cat</literal> son mapeadas a la
+            misma tabla. En el caso de la propiedad <literal>name</literal>, la hemos mapeado
+            con una declaraci&#x00f3;n expl&#x00ed;cita de columna de base de datos. Esto es
+            especialmente &#x00fa;til cuando el esquema de base de datos es generado
+            autom&#x00e1;ticamente (como sentencias DDL de SQL) desde la declaraci&#x00f3;n
+            de mapeo con la herramienta <emphasis>SchemaExport</emphasis> de Hibernate.
+            Todas las dem&#x00e1;s propiedades son mapeadas usando la configuraci&#x00f3;n
+            por defecto de Hibernate, que es lo que necesitas la mayor&#x00ed;a del tiempo.
+            La tabla <literal>CAT</literal> en la base de datos se ve as&#x00ed; como:
+        </para>
+
+        <programlisting><![CDATA[ Columna |         Tipo          | Modificadores
+--------+-----------------------+-----------
+ cat_id | character(32)         | not null
+ name   | character varying(16) | not null
+ sex    | character(1)          |
+ weight | real                  |
+Indexes: cat_pkey primary key btree (cat_id)]]></programlisting>
+
+        <para>
+            Ahora debes crear esta tabla manualmente en tu base de datos, y luego leer el
+            <xref linkend="toolsetguide"/> si quieres automatizar este paso con la
+            herramienta <literal>hbm2ddl</literal>. Esta herramienta puede crear un
+            DDL SQL completo, incluyendo definici&#x00f3;n de tablas, restricciones
+            personalizadas de tipo de columnas, restricciones de unicidad e &#x00ed;ndices.
+        </para>
+
+    </sect1>
+
+    <sect1 id="quickstart-playingwithcats" revision="2">
+        <title>Jugando con gatos</title>
+
+        <para>
+            Ahora estamos listos para comenzar la <literal>Session</literal> de Hibernate.
+            Es el <emphasis>manejador de persistencia</emphasis> que usamos para almacenar
+            y traer <literal>Cat</literal>s hacia y desde la base de datos. Pero primero,
+            tenemos que obtener una <literal>Session</literal> (unidad de trabajo de Hibernate)
+            de la <literal>SessionFactory</literal>:
+        </para>
+
+        <programlisting><![CDATA[SessionFactory sessionFactory =
+            new Configuration().configure().buildSessionFactory();]]></programlisting>
+
+        <para>
+                        La llamada a <literal>configure()</literal> carga el fichero de
+                        configuraci&#x00f3;n <literal>hibernate.cfg.xml</literal> e
+                        inicializa la instancia de <literal>Configuration</literal>.
+                        Puedes establecer otras propiedades (e incluso cambiar los metadatos de mapeo)
+                        accediendo a la <literal>Configuration</literal> <emphasis>antes</emphasis>
+                        que construyas la <literal>SessionFactory</literal> (que es inmutable).
+                        ¿D&#x00f3;nde creamos la <literal>SessionFactory</literal> y c&#x00f3;mo
+                        accedemos a ella en nuestra aplicaci&#x00f3;n?
+        </para>
+
+        <para>
+            Una <literal>SessionFactory</literal> usualmente se construye una vez,
+            por ejemplo, al arrancar con un servlet <emphasis>load-on-startup</emphasis>.
+            Esto significa tambi&#x00e9;n que no debes mantenerla en una variable de instancia
+            en tus servlets, sino en alguna otro sitio. Adem&#x00e1;s, necesitamos alg&#x00fa;n
+            tipo de <emphasis>Singleton</emphasis>, de modo que podamos acceder a la
+            <literal>SessionFactory</literal> f&#x00e1;cilmente en el c&#x00f3;digo de
+            aplicaci&#x00f3;n. El siguiente enfoque mostrado resuelve ambos problemas:
+            configuraci&#x00f3;n de arranque y f&#x00e1;cil acceso a una
+            <literal>SessionFactory</literal>.
+        </para>
+
+		<para>
+                    Implementamos una clase de ayuda <literal>HibernateUtil</literal>:
+		</para>
+
+		<programlisting><![CDATA[import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+    private static Logger log = LoggerFactory.getLogger(HibernateUtil.class);
+
+    private static final SessionFactory sessionFactory;
+
+    static {
+        try {
+            // Create the SessionFactory
+            sessionFactory = new Configuration().configure().buildSessionFactory();
+        } catch (Throwable ex) {
+            // Make sure you log the exception, as it might be swallowed
+            log.error("Initial SessionFactory creation failed.", ex);
+            throw new ExceptionInInitializerError(ex);
+        }
+    }
+
+    public static final ThreadLocal session = new ThreadLocal();
+
+    public static Session currentSession() {
+        Session s = (Session) session.get();
+        // Open a new Session, if this Thread has none yet
+        if (s == null) {
+            s = sessionFactory.openSession();
+            session.set(s);
+        }
+        return s;
+    }
+
+    public static void closeSession() {
+        Session s = (Session) session.get();
+        if (s != null)
+            s.close();
+        session.set(null);
+    }
+}]]></programlisting>
+
+        <para>
+            Esta clase no s&#x00f3;lo cuida de la <literal>SessionFactory</literal>
+            con su inicializador static, sino que adem&#x00e1;s tiene una variable
+            <literal>ThreadLocal</literal> que tiene la <literal>Session</literal>
+            para la hebra actual. Aseg&#x00fa;rate de entender el concepto Java de una
+            variable local a una hebra antes de intentar usar esta ayuda. Una clase
+            <literal>HibernateUtil</literal> m&#x00e1;s compleja y potente puede
+            encontrarse en <literal>CaveatEmptor</literal>, http://caveatemptor.hibernate.org/
+        </para>
+
+        <para>
+            Una <literal>SessionFactory</literal> es segura entre hebras, muchas hebras pueden
+            acceder a ella concurrentemente y pedirle <literal>Session</literal>s. Una
+            <literal>Session</literal> no es un objeto seguro entre hebras que representa
+            una sola unidad-de-trabajo con la base de datos. Las <literal>Session</literal>s
+            se abren desde una <literal>SessionFactory</literal> y son cerradas cuando
+            todo el trabajo est&#x00e1; completo. Un ejemplo en el m&#x00e9;todo
+            <literal>process()</literal> de tu servlet podr&#x00ed;a parecerse a esto
+            (sin manejo de excepciones):
+        </para>
+
+        <programlisting><![CDATA[Session session = HibernateUtil.currentSession();
+Transaction tx = session.beginTransaction();
+
+Cat princess = new Cat();
+princess.setName("Princess");
+princess.setSex('F');
+princess.setWeight(7.4f);
+
+session.save(princess);
+
+tx.commit();
+HibernateUtil.closeSession();]]></programlisting>
+
+        <para>
+            En una <literal>Session</literal>, cada operaci&#x00f3;n de base de datos
+            ocurre dentro de una transacci&#x00f3;n que a&#x00ed;sla las operaciones
+            de base de datos (incluso operaciones de s&#x00f3;lo lectura).
+            Usamos la API de <literal>Transaction</literal> de Hibernate para
+            abstraer de la estrategia de transacciones subyacente (en nuestro caso,
+            transacciones JDBC). Esto permite que nuestro c&#x00f3;digo sea desplegado
+            con transacciones manejadas por contenedor (usando JTA) sin cambio alguno.
+        </para>
+
+        <para>
+            Observa que puedes llamar <literal>HibernateUtil.currentSession();</literal>
+            tantas veces como quieras, siempre obtendr&#x00e1;s la <literal>Session</literal>
+            actual de esta hebra. Tienes que asegurarte que la <literal>Session</literal>
+            sea cerrada despu&#x00e9;s que se complete tu unidad-de-trabajo, ya sea en
+            c&#x00f3;digo de tu servlet o en un filtro de servlet antes que la respuesta HTTP
+            sea enviada. El bonito efecto colateral de la segunda opci&#x00f3;n es la
+            f&#x00e1;cil inicializaci&#x00f3;n perezosa: la <literal>Session</literal> todav&#x00ed;a
+            est&#x00e1; abierta cuando se dibuja la vista, de modo que Hibernate puede cargar
+            objetos no inicializados mientras navegas tu actual grafo de objetos.
+        </para>
+
+        <para>
+            Hibernate tiene varios m&#x00e9;todos que pueden ser usados para traer
+            objetos desde la base de datos. La forma m&#x00e1;s flexible es usando
+            el Lenguaje de Consulta de Hibernate (Hibernate Query Language o HQL),
+            que es una extensi&#x00f3;n orientada a objetos de SQL f&#x00e1;cil de
+            aprender:
+        </para>
+
+        <programlisting><![CDATA[Transaction tx = session.beginTransaction();
+
+Query query = session.createQuery("select c from Cat as c where c.sex = :sex");
+query.setCharacter("sex", 'F');
+for (Iterator it = query.iterate(); it.hasNext();) {
+    Cat cat = (Cat) it.next();
+    out.println("Female Cat: " + cat.getName() );
+}
+
+tx.commit();]]></programlisting>
+
+        <para>
+            Hibernate tambi&#x00e9;n ofrece una API <emphasis>consulta por criterios</emphasis>
+            orientada a objetos que puede ser usada para formular consultas de tipo seguro.
+            Por supuesto, Hibernate usa <literal>PreparedStatement</literal>s y ligado de
+            par&#x00e1;metros para toda la comunicaci&#x00f3;n SQL con la base de datos.
+            Tambi&#x00e9;n puedes usar la funcionalidad de consulta SQL directa de Hibernate
+            u obtener una conexi&#x00f3;n plana de JDBC de una <literal>Session</literal> 
+            en casos raros.
+        </para>
+
+    </sect1>
+
+    <sect1 id="quickstart-summary" revision="1">
+        <title>Finalmente</title>
+
+        <para>
+            Rasgu&#x00f1;amos solamente la superficie de Hibernate en este peque&#x00f1;o
+            tutorial. Por favor, observa que no incluimos ning&#x00fa;n c&#x00f3;digo
+            espec&#x00ed;fico de servlet en nuestros ejemplos. Tienes que crear un servlet
+            por t&#x00ed; mismo e insertar el c&#x00f3;digo de Hibernate como lo veas
+            ubicado.
+        </para>
+
+        <para>
+            Ten en mente que Hibernate, como capa de acceso a datos, est&#x00e1; firmemente
+            integrado dentro de tu aplicaci&#x00f3;n. Usualmente, todas las otras capas dependen
+            del mecanismo de persistencia. Aseg&#x00fa;rate de entender las implicaciones
+            de este dise&#x00f1;o.
+        </para>
+
+        <para>
+            Para un ejemplo de aplicaci&#x00f3;n m&#x00e1;s compleja, ver
+            http://caveatemptor.hibernate.org/ y echa una mirada a los
+            otros tutoriales con links en http://www.hibernate.org/Documentation
+        </para>
+
+    </sect1>
+
+</chapter>

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/session_api.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/session_api.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/session_api.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/session_api.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,1224 @@
+<chapter id="objectstate">
+    <title>Trabajando con objetos</title>
+
+    <para>
+        Hibernate es una soluci&#x00f3;n completa de mapeo objeto/relacional que no s&#x00f3;lo
+        abstrae al desarrollador de los detalles del sistema de manejo de base datos
+        subyacente, sino que adem&#x00e1;s ofrece <emphasis>manejo de estado</emphasis> de
+        objetos. Esto es, al contrario del manejo de <literal>sentencias</literal>
+        SQL en capas comunes de persistencia JDBC/SQL, una vista de la persistencia
+        en aplicaciones Java muy natural y orientada a objetos.
+    </para>
+
+    <para>
+        En otras palabras, los desarroladores de aplicaciones Hibernate deben siempre
+        pensar en el <emphasis>estado</emphasis> de sus objetos, y no necesariamente
+        en la ejecuci&#x00f3;n de sentencias SQL. Esta parte es cuidada por Hibernate y es
+        s&#x00f3;lo relevante para el desarrollador de la aplicaci&#x00f3;n al afinar el rendimiento
+        del sistema.
+    </para>
+
+    <sect1 id="objectstate-overview">
+        <title>Estados de objeto de Hibernate</title>
+
+        <para>
+            Hibernate define y soporta los siguientes estados de objeto:
+        </para>
+
+        <itemizedlist>
+            <listitem>
+                <para>
+                    <emphasis>Transitorio</emphasis> - un objeto es transitorio si ha sido
+                    reci&#x00e9;n instanciado usando el operador <literal>new</literal>, y no est&#x00e1;
+                    asociado a una <literal>Session</literal> de Hibernate. No tiene una
+                    representaci&#x00f3;n persistente en la base de datos y no se le ha asignado un
+                    valor identificador. Las instancias transitorias ser&#x00e1;n destru&#x00ed;das por el
+                    recolector de basura si la aplicaci&#x00f3;n no mantiene m&#x00e1;s una referencia.
+                    Usa la <literal>Session</literal> de Hibernate para hacer un objeto
+                    persistente (y deja que Hibernate cuide de las sentencias SQL que necesitan
+                    ejecutarse para esta transici&#x00f3;n).
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis>Persistente</emphasis> - una instancia persistente tiene una
+                    representaci&#x00f3;n en la base de datos y un valor identificador. Puede haber
+                    sido salvado o cargado, sin embargo, est&#x00e1; por definici&#x00f3;n en el &#x00e1;mbito de
+                    una <literal>Session</literal>. Hibernate detectar&#x00e1; cualquier cambio hecho
+                    a un objeto en estado persistentey sincronizar&#x00e1; el estado con la base de
+                    datos cuando se complete la unidad de trabajo. Los desarrolladores no ejecutan
+                    sentencias <literal>UPDATE</literal> manuales, o sentencias <literal>DELETE</literal>
+                    cuando un objeto debe ser hecho transitorio.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <emphasis>Separado (detached)</emphasis> - una instancia separada es un objeto
+                    que ha sido hecho persistente, pero su <literal>Session</literal> ha sido cerrada.
+                    La referencia al objeto todav&#x00ed;a es v&#x00e1;lida, por supuesto, y la instancia separada
+                    podr&#x00ed;a incluso ser modificada en este estado. Una instancia separada puede ser
+                    re-unida a una nueva <literal>Session</literal> en un punto posterior en el tiempo,
+                    haci&#x00e9;ndola persistente de nuevo (con todas las modificaciones). Este aspecto
+                    habilita un modelo de programaci&#x00f3;n para unidades de trabajo de ejecuci&#x00f3;n larga
+                    que requieren tiempo-para-pensar del usuario. Las llamamos <emphasis>transaccciones
+                    de aplicaci&#x00f3;n</emphasis>, es decir, una unidad de trabajo desde el punto de vista
+                    del usuario.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Discutiremos ahora los estados y transiciones de estados (y los m&#x00e9;todos de Hibernate que
+            disparan una transici&#x00f3;n) en m&#x00e1;s detalle:
+        </para>
+
+    </sect1>
+
+    <sect1 id="objectstate-makingpersistent" revision="1">
+        <title>Haciendo los objetos persistentes</title>
+
+        <para>
+            Las instancias reci&#x00e9;n instanciadas de una clase persistente son consideradas
+            <emphasis>transitorias</emphasis> por Hibernate. Podemos hacer una instancia
+            transitoria <emphasis>persistente</emphasis> asoci&#x00e1;ndola con una sesi&#x00f3;n:
+        </para>
+
+        <programlisting><![CDATA[DomesticCat fritz = new DomesticCat();
+fritz.setColor(Color.GINGER);
+fritz.setSex('M');
+fritz.setName("Fritz");
+Long generatedId = (Long) sess.save(fritz);]]></programlisting>
+
+        <para>
+            Si <literal>Cat</literal> tiene un identificador generado, el identificador es
+            generado y asignado al <literal>cat</literal> cuando se llama a <literal>save()</literal>.
+            Si <literal>Cat</literal> tiene un identificador <literal>assigned</literal>,
+            o una clave compuesta, el identificador debe ser asignado a la instancia de
+            <literal>cat</literal> antes de llamar a <literal>save()</literal>. Puedes tambi&#x00e9;n
+            usar <literal>persist()</literal> en vez de <literal>save()</literal>, con la sem&#x00e1;ntica
+            definida en el temprano borrador de EJB3.
+        </para>
+        
+        <para>
+            Alternativamente, puedes asignar el identificador usando una versi&#x00f3;n sobrecargada
+            de <literal>save()</literal>.
+        </para>
+
+<programlisting><![CDATA[DomesticCat pk = new DomesticCat();
+pk.setColor(Color.TABBY);
+pk.setSex('F');
+pk.setName("PK");
+pk.setKittens( new HashSet() );
+pk.addKitten(fritz);
+sess.save( pk, new Long(1234) );]]></programlisting>
+        
+        <para>
+            Si el objeto que haces persistente tiene objetos asociados (por ejemplo,
+            la colecci&#x00f3;n <literal>kittens</literal> en el ejemplo anterior), estos
+            objetos pueden ser hechos persistentes en cualquier orden que quieras
+            a menos que tengas una restricci&#x00f3;n <literal>NOT NULL</literal> sobre una
+            columna clave for&#x00e1;nea. Nunca hay riesgo de violar restricciones de clave
+            for&#x00e1;nea. Sin embargo, podr&#x00ed;as violar una restricci&#x00f3;n <literal>NOT NULL</literal>
+            si llamas a <literal>save()</literal> sobre objetos en orden err&#x00f3;neo.
+        </para>
+        
+        <para>
+            Usualmente no te preocupas con este detalle, pues muy probablemente usar&#x00e1;s
+            la funcionalidad de <emphasis>persistencia transitiva</emphasis> de Hibernate
+            para salvar los objetos asociados autom&#x00e1;ticamente. Entonces, ni siquiera ocurren
+            violaciones de restricciones <literal>NOT NULL</literal> - Hibernate cuidar&#x00e1; de todo.
+            La persistencia transitiva se discute m&#x00e1;s adelante en este cap&#x00ed;tulo.
+        </para>
+        
+    </sect1>
+
+    <sect1 id="objectstate-loading">
+        <title>Cargando un objeto</title>
+
+        <para>
+            Los m&#x00e9;todos <literal>load()</literal> de <literal>Session</literal> te brindan
+            una forma de traer una instancia persistente si ya saves su identificador.
+            <literal>load()</literal> toma un objeto clase y cargar&#x00e1; el estado dentro de
+            una instancia reci&#x00e9;n instanciada de esta clase, en estado persistente.
+        </para>
+
+        <programlisting><![CDATA[Cat fritz = (Cat) sess.load(Cat.class, generatedId);]]></programlisting>
+
+<programlisting><![CDATA[// you need to wrap primitive identifiers
+long id = 1234;
+DomesticCat pk = (DomesticCat) sess.load( DomesticCat.class, new Long(id) );]]></programlisting>
+
+        <para>
+            Alternativamente, puedes cargar estado dentro de una instancia dada:
+        </para>
+
+<programlisting><![CDATA[Cat cat = new DomesticCat();
+// load pk's state into cat
+sess.load( cat, new Long(pkId) );
+Set kittens = cat.getKittens();]]></programlisting>
+
+        <para>
+            Nota que <literal>load()</literal> lanzar&#x00e1; una excepci&#x00f3;n irrecuperable si no
+            hay una fila correspondiente en base de datos. Si la clase es mapeada con un
+            proxy, <literal>load()</literal> s&#x00f3;lo devuelve un proxy no inicializado y no
+            llamar&#x00e1; realmente a la base de datos hasta que invoques un m&#x00e9;todo del proxy.
+            Este comportamiento es muy &#x00fa;til si deseas crear una asociaci&#x00f3;n a un objeto
+            sin cargarlo realmente de la base de datos. Permite adem&#x00e1;s que m&#x00fa;ltiples
+            instancias sean cargadas como un lote si se define <literal>batch-size</literal>
+            para el mapeo de la clase.
+        </para>
+        
+        <para>
+            Si no tienes certeza que exista una fila correspondiente, debes usar el
+            m&#x00e9;todo <literal>get()</literal>, que llama a la base de datos inmediatamente
+            y devuelve nulo si no existe una fila correspondiente.
+        </para>
+        
+        <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id);
+if (cat==null) {
+    cat = new Cat();
+    sess.save(cat, id);
+}
+return cat;]]></programlisting>
+
+        <para>
+            Puedes incluso cargar un objeto usando un <literal>SELECT ... FOR UPDATE</literal> de SQL,
+            usando un <literal>LockMode</literal>. Ver la documentaci&#x00f3;n de la API para m&#x00e1;s
+            informaci&#x00f3;n.
+        </para>
+
+        <programlisting><![CDATA[Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);]]></programlisting>
+        
+        <para>
+            Ten en cuenta que <emphasis>ninguna</emphasis> instancia asociada o colecci&#x00f3;n contenida es
+            selecciona <literal>FOR UPDATE</literal>, a menos que decidas especificar 
+            <literal>lock</literal> o <literal>all</literal> como un estilo de cascada para la
+            asociaci&#x00f3;n.
+        </para>
+        
+        <para>
+            Es posible volver a cargar un objeto y todas sus colecciones en cualquier momento,
+            usando el m&#x00e9;todo <literal>refresh()</literal>. Esto es &#x00fa;til cuando se usan disparadores de
+            base de datos para inicializar algunas de las propiedades del objeto.
+        </para>
+        
+        <programlisting><![CDATA[sess.save(cat);
+sess.flush(); //force the SQL INSERT
+sess.refresh(cat); //re-read the state (after the trigger executes)]]></programlisting>
+
+        <para>
+            Una cuesti&#x00f3;n importante aparece usualmente en este punto: ¿Cu&#x00e1;nto carga Hibernate de
+            la base de datos y cu&#x00e1;ntos <literal>SELECT</literal>s de SQL usar&#x00e1;? Esto depende de la
+            <emphasis>estrategia de recuperaci&#x00f3;n</emphasis> y se explica en <xref linkend="performance-fetching"/>.
+        </para>
+
+    </sect1>
+
+    <sect1 id="objectstate-querying" revision="1">
+        <title>Consultando</title>
+
+        <para>
+            Si no sabes los identificadores de los objetos que est&#x00e1;s buscando,
+            necesitas una consulta. Hibernate soporta un lenguaje de consulta
+            orientado a objetos (HQL) f&#x00e1;cil de usar pero potente. Para la creaci&#x00f3;n
+            de consultas program&#x00e1;ticas, Hibernate soporta una funcionalidad sofisticada
+            de consulta de Criteria y Example (QBC and QBE). Tambi&#x00e9;n puedes expresar tu
+            consulta en el SQL nativo de tu base de datos, con soporte opcional de Hibernate
+            para la conversi&#x00f3;n del conjunto resultado en objetos.
+        </para>
+
+        <sect2 id="objectstate-querying-executing">
+            <title>Ejecutando consultas</title>
+
+            <para>
+                Las consultas HQL y SQL nativas son representadas con una instancia de
+                <literal>org.hibernate.Query</literal>. Esta interface ofrece m&#x00e9;todos para
+                la ligaci&#x00f3;n de par&#x00e1;metros, manejo del conjunto resultado, y para la
+                ejecuci&#x00f3;n de la consulta real. Siempre obtienes una <literal>Query</literal>
+                usando la <literal>Session</literal> actual:
+            </para>
+
+        <programlisting><![CDATA[List cats = session.createQuery(
+    "from Cat as cat where cat.birthdate < ?")
+    .setDate(0, date)
+    .list();
+
+List mothers = session.createQuery(
+    "select mother from Cat as cat join cat.mother as mother where cat.name = ?")
+    .setString(0, name)
+    .list();
+
+List kittens = session.createQuery(
+    "from Cat as cat where cat.mother = ?")
+    .setEntity(0, pk)
+    .list();
+
+Cat mother = (Cat) session.createQuery(
+    "select cat.mother from Cat as cat where cat = ?")
+    .setEntity(0, izi)
+    .uniqueResult();]]></programlisting>
+
+            <para>
+                Una consulta se ejecuta usualmente invocando a <literal>list()</literal>,
+                el resultado de la consulta ser&#x00e1; cargado completamente dentro de una
+                colecci&#x00f3;n en memoria. Las instancias de entidad tra&#x00ed;das por una consulta
+                est&#x00e1;n en estado persistente. El m&#x00e9;todo <literal>uniqueResult()</literal>
+                ofrece un atajo si sabes que tu consulta devolver&#x00e1; s&#x00f3;lo un objeto.
+            </para>
+
+            <sect3 id="objectstate-querying-executing-iterate">
+                <title>Iterando los resultados</title>
+
+                <para>
+                    Ocasionalmente, podr&#x00ed;as ser capaz de lograr mejor rendimiento al ejecutar la consulta
+                    usando el m&#x00e9;todo <literal>iterate()</literal>. Esto s&#x00f3;lo ser&#x00e1; en el caso que esperes
+                    que las instancias reales de entidad devueltas por la consulta est&#x00e9;n ya en la sesi&#x00f3;n
+                    o cach&#x00e9; de segundo nivel. Si todav&#x00ed;a no est&#x00e1;n en cach&#x00e9;, <literal>iterate()</literal>
+                    ser&#x00e1; m&#x00e1;s lento que <literal>list()</literal> y podr&#x00ed;a requerir muchas llamadas a la
+                    base de datos para una consulta simple, usualmente <emphasis>1</emphasis> para la
+                    selecci&#x00f3;n inicial que solamente devuelve identificadores, y <emphasis>n</emphasis>
+                    selecciones adicionales para inicializar las instancias reales.
+                </para>
+
+                <programlisting><![CDATA[// fetch ids
+Iterator iter = sess.createQuery("from eg.Qux q order by q.likeliness").iterate();
+while ( iter.hasNext() ) {
+    Qux qux = (Qux) iter.next();  // fetch the object
+    // something we couldnt express in the query
+    if ( qux.calculateComplicatedAlgorithm() ) {
+        // delete the current instance
+        iter.remove();
+        // dont need to process the rest
+        break;
+    }
+}]]></programlisting>
+            </sect3>
+            
+            <sect3 id="objectstate-querying-executing-tuples">
+                <title>Consultas que devuelven tuplas</title>
+
+                <para>
+                    Las consultas de Hibernate a veces devuelven tuplas de objetos, en cuyo caso
+                    cada tupla se devuelve como un array:
+                </para>
+
+                <programlisting><![CDATA[Iterator kittensAndMothers = sess.createQuery(
+            "select kitten, mother from Cat kitten join kitten.mother mother")
+            .list()
+            .iterator();
+
+while ( kittensAndMothers.hasNext() ) {
+    Object[] tuple = (Object[]) kittensAndMothers.next();
+    Cat kitten = (Cat) tuple[0];
+    Cat mother = (Cat) tuple[1];
+    ....
+}]]></programlisting>
+
+            </sect3>
+
+            <sect3 id="objectstate-querying-executing-scalar">
+                <title>Resultados escalares</title>
+
+                <para>
+                    Las consultas pueden especificar una propiedad de una clase en la cl&#x00e1;usula
+                    <literal>select</literal>. Pueden incluso llamar a funciones de agregaci&#x00f3;n SQL.
+                    Las propiedades o agregaciones son considerados resultados "escalares"
+                    (y no entidades en estado persistente).
+                </para>
+
+                <programlisting><![CDATA[Iterator results = sess.createQuery(
+        "select cat.color, min(cat.birthdate), count(cat) from Cat cat " +
+        "group by cat.color")
+        .list()
+        .iterator();
+
+while ( results.hasNext() ) {
+    Object[] row = results.next();
+    Color type = (Color) row[0];
+    Date oldest = (Date) row[1];
+    Integer count = (Integer) row[2];
+    .....
+}]]></programlisting>
+
+            </sect3>
+
+            <sect3 id="objectstate-querying-executing-parameters">
+                <title>Ligaci&#x00f3;n de par&#x00e1;metros</title>
+
+                <para>
+                    Se proveen m&#x00e9;todos en <literal>Query</literal> para ligar valores a
+                    par&#x00e1;metros con nombre o par&#x00e1;metros <literal>?</literal> de estilo JDBC.
+                    <emphasis>Al contrario de JDBC, Hibernate numera los par&#x00e1;metros desde cero.</emphasis>
+                    Los par&#x00e1;metros con nombre son identificadores de la forma <literal>:name</literal>
+                    en la cadena de la consulta. Las ventajas de los par&#x00e1;metros con nombre son:
+                </para>
+
+                <itemizedlist spacing="compact">
+                    <listitem>
+                        <para>
+                            los par&#x00e1;metros con nombre son insensibles al orden en que aparecen
+                            en la cadena de consulta
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+                            pueden aparecer m&#x00fa;ltiples veces en la misma consulta
+                        </para>
+                    </listitem>
+                    <listitem>
+                        <para>
+                            son auto-documentados
+                        </para>
+                    </listitem>
+                </itemizedlist>
+
+                <programlisting><![CDATA[//named parameter (preferred)
+Query q = sess.createQuery("from DomesticCat cat where cat.name = :name");
+q.setString("name", "Fritz");
+Iterator cats = q.iterate();]]></programlisting>
+
+                <programlisting><![CDATA[//positional parameter
+Query q = sess.createQuery("from DomesticCat cat where cat.name = ?");
+q.setString(0, "Izi");
+Iterator cats = q.iterate();]]></programlisting>
+
+                <programlisting><![CDATA[//named parameter list
+List names = new ArrayList();
+names.add("Izi");
+names.add("Fritz");
+Query q = sess.createQuery("from DomesticCat cat where cat.name in (:namesList)");
+q.setParameterList("namesList", names);
+List cats = q.list();]]></programlisting>
+
+            </sect3>
+
+            <sect3 id="objectstate-querying-executing-pagination">
+                <title>Paginaci&#x00f3;n</title>
+
+                <para>
+                    Si necesitas especificar l&#x00ed;mites sobre tu conjunto resultado (el n&#x00fa;mero m&#x00e1;ximo de filas
+                    que quieras traer y/o la primera fila que quieras traer) debes usar los m&#x00e9;todos de la
+                    interface <literal>Query</literal>:
+                </para>
+
+                <programlisting><![CDATA[Query q = sess.createQuery("from DomesticCat cat");
+q.setFirstResult(20);
+q.setMaxResults(10);
+List cats = q.list();]]></programlisting>
+
+                <para>
+                    Hibernate sabe c&#x00f3;mo traducir este l&#x00ed;mite de consulta al SQL nativo de tu
+                    DBMS.
+                </para>
+
+            </sect3>
+
+            <sect3 id="objectstate-querying-executing-scrolling">
+                <title>Iteraci&#x00f3;n scrollable</title>
+
+                <para>
+                    Si tu driver JDBC soporta <literal>ResultSet</literal>s scrollables, la
+                    interface <literal>Query</literal> puede ser usada para obtener un objeto
+                    <literal>ScrollableResults</literal>, que permite una navegaci&#x00f3;n flexible
+                    de los resultados de consulta.
+                </para>
+
+                <programlisting><![CDATA[Query q = sess.createQuery("select cat.name, cat from DomesticCat cat " +
+                            "order by cat.name");
+ScrollableResults cats = q.scroll();
+if ( cats.first() ) {
+
+    // find the first name on each page of an alphabetical list of cats by name
+    firstNamesOfPages = new ArrayList();
+    do {
+        String name = cats.getString(0);
+        firstNamesOfPages.add(name);
+    }
+    while ( cats.scroll(PAGE_SIZE) );
+
+    // Now get the first page of cats
+    pageOfCats = new ArrayList();
+    cats.beforeFirst();
+    int i=0;
+    while( ( PAGE_SIZE > i++ ) && cats.next() ) pageOfCats.add( cats.get(1) );
+
+}
+cats.close()]]></programlisting>
+
+                <para>
+                    Nota que se requiere una conexi&#x00f3;n de base de datos abierta (y cursor) para esta
+                    funcionalidad, usa <literal>setMaxResult()</literal>/<literal>setFirstResult()</literal>
+                    si necesitas la funcionalidad de paginaci&#x00f3;n fuera de l&#x00ed;nea.
+                </para>
+
+            </sect3>
+
+            <sect3 id="objectstate-querying-executing-named">
+                <title>Externalizando consultas con nombre</title>
+
+                <para>
+                    Puedes adem&#x00e1;s definir consultas con nombre en el documento de mapeo.
+                    (Recuerda usar una secci&#x00f3;n <literal>CDATA</literal> si tu consulta
+                    contiene caracteres que puedan ser interpretados como etiquetado.)
+                </para>
+
+                <programlisting><![CDATA[<query name="eg.DomesticCat.by.name.and.minimum.weight"><![CDATA[
+    from eg.DomesticCat as cat
+        where cat.name = ?
+        and cat.weight > ?
+] ]></query>]]></programlisting>
+
+                <para>
+                    La ligaci&#x00f3;n de par&#x00e1;metros y ejecuci&#x00f3;n se hace program&#x00e1;ticamente:
+                </para>
+
+                <programlisting><![CDATA[Query q = sess.getNamedQuery("eg.DomesticCat.by.name.and.minimum.weight");
+q.setString(0, name);
+q.setInt(1, minWeight);
+List cats = q.list();]]></programlisting>
+
+                <para>
+                    Nota que el c&#x00f3;digo real del programa es independiente del lenguaje de consulta
+                    usado; puedes adem&#x00e1;s definir consultas SQL nativas en metadatos, o migrar
+                    consultas existentes a Hibernate coloc&#x00e1;ndolas en ficheros de mapeo.
+                </para>
+
+            </sect3>
+
+        </sect2>
+
+        <sect2 id="objectstate-filtering" revision="1">
+            <title>Filtrando colecciones</title>
+            <para>
+                Un <emphasis>filtro</emphasis> de colecci&#x00f3;n es un tipo especial de consulta que puede ser
+                aplicado a una colecci&#x00f3;n persistente o array. La cadena de consulta puede referirse a
+                <literal>this</literal>, significando el elemento de colecci&#x00f3;n actual.
+            </para>
+
+            <programlisting><![CDATA[Collection blackKittens = session.createFilter(
+    pk.getKittens(), 
+    "where this.color = ?")
+    .setParameter( Color.BLACK, Hibernate.custom(ColorUserType.class) )
+    .list()
+);]]></programlisting>
+        
+            <para>
+                La colecci&#x00f3;n devuelta es considerada un bag, y es una copia de la colecci&#x00f3;n
+                dada. La colecci&#x00f3;n original no es modificada (esto es contrario a la implicaci&#x00f3;n
+                del nombre "filtro", pero consistente con el comportamiento esperado).
+            </para>
+
+            <para>
+                Observa que los filtros no requieren una cl&#x00e1;usula <literal>from</literal> (aunque pueden
+                tener uno si se requiere). Los filtros no est&#x00e1;n limitados a devolver los elementos de
+                colecci&#x00f3;n por s&#x00ed; mismos.
+            </para>
+
+            <programlisting><![CDATA[Collection blackKittenMates = session.createFilter(
+    pk.getKittens(), 
+    "select this.mate where this.color = eg.Color.BLACK.intValue")
+    .list();]]></programlisting>
+
+            <para>
+                Incluso una consulta de filtro vac&#x00ed;o es &#x00fa;til, por ejemplo, para cargar un
+                subconjunto de elementos en una colecci&#x00f3;n enorme:
+            </para>
+
+            <programlisting><![CDATA[Collection tenKittens = session.createFilter(
+    mother.getKittens(), "")
+    .setFirstResult(0).setMaxResults(10)
+    .list();]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="objecstate-querying-criteria" revision="1">
+           <title>Consultas de criterios</title>
+
+            <para>
+                HQL es extremadamente potente pero algunos desarrolladores prefieren construir
+                consultas din&#x00e1;micamente usando una API orientada a objetos, en vez construir
+                cadenas de consulta. Hibernate provee una API intuitiva de consulta <literal>Criteria</literal>
+                para estos casos:
+            </para>
+
+            <programlisting><![CDATA[Criteria crit = session.createCriteria(Cat.class);
+crit.add( Restrictions.eq( "color", eg.Color.BLACK ) );
+crit.setMaxResults(10);
+List cats = crit.list();]]></programlisting>
+    
+            <para>
+                Las APIs de <literal>Criteria</literal> y la asociada <literal>Example</literal>
+                son discutidas en m&#x00e1;s detalle en <xref linkend="querycriteria"/>.
+            </para>
+
+        </sect2>
+
+        <sect2 id="objectstate-querying-nativesql" revision="2">
+            <title>Consultas en SQL nativo</title>
+
+            <para>
+                Puedes expresar una consulta en SQL, usando <literal>createSQLQuery()</literal> y
+                dejando que Hibernate cuide del mapeo de los conjuntos resultado a objetos.
+                Nota que puedes llamar en cualquier momento a <literal>session.connection()</literal> y
+                usar la <literal>Connection</literal> JDBC directamente. Si eliges usar la API de
+                Hibernate, debes encerrar los alias de SQL entre llaves:
+            </para>
+
+            <programlisting><![CDATA[List cats = session.createSQLQuery("SELECT {cat.*} FROM CAT {cat} WHERE ROWNUM<10")
+    .addEntity("cat", Cat.class)
+.list();]]></programlisting>
+                
+            <programlisting><![CDATA[List cats = session.createSQLQuery(
+    "SELECT {cat}.ID AS {cat.id}, {cat}.SEX AS {cat.sex}, " +
+           "{cat}.MATE AS {cat.mate}, {cat}.SUBCLASS AS {cat.class}, ... " +
+    "FROM CAT {cat} WHERE ROWNUM<10")
+    .addEntity("cat", Cat.class)
+.list()]]></programlisting>
+
+            <para>
+                Las consultas SQL pueden contener par&#x00e1;metros con nombre y posicionales, al igual que
+                las consultas de Hibernate. Puede encontrarse m&#x00e1;s informaci&#x00f3;n sobre consultas en SQL
+                nativo en <xref linkend="querysql"/>.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="objectstate-modifying" revision="1">
+        <title>Modificando objetos persistentes</title>
+
+        <para>
+            Las <emphasis>instancias persistentes transaccionales</emphasis> (es decir, objetos cargados,
+            creados o consultados por la <literal>Session</literal>) pueden ser manipulados por la
+            aplicaci&#x00f3;n y cualquier cambio al estado persistente ser&#x00e1; persistido cuando la <literal>Session</literal>
+            sea <emphasis>limpiada (flushed)</emphasis> (discutido m&#x00e1;s adelante en este cap&#x00ed;tulo). No hay
+            necesidad de llamar un m&#x00e9;todo en particular (como <literal>update()</literal>, que tiene un
+            prop&#x00f3;sito diferente) para hacer persistentes tus modificaciones. De modo que la forma m&#x00e1;s
+            directa de actualizar el estado de un objeto es cargarlo con <literal>load()</literal>,
+            y entonces manipularlo directamente, mientras la <literal>Session</literal> est&#x00e1; abierta:
+        </para>
+
+        <programlisting><![CDATA[DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
+cat.setName("PK");
+sess.flush();  // changes to cat are automatically detected and persisted]]></programlisting>
+
+        <para>
+            A veces este modelo de programaci&#x00f3;n es ineficiente pues podr&#x00ed;a requerir una
+            <literal>SELECT</literal> de SQL (para cargar un objeto) y un <literal>UPDATE</literal>
+            de SQL (para hacer persistentes sus datos actualizados) en la misma sesi&#x00f3;n. Por lo tanto,
+            Hibernate ofrece un enfoque alternativo, usando instancias separadas (detached).
+        </para>
+
+        <para>
+            <emphasis>Nota que Hibernate no ofreve su propia API para ejecuci&#x00f3;n directa de
+            sentencias <literal>UPDATE</literal> o <literal>DELETE</literal>. Hibernate es un
+            servicio de <emphasis>gesti&#x00f3;n de estado</emphasis>, no tienes que pensar en
+            <literal>sentencias</literal> para usarlo. JDBC es una API perfecta para ejecutar
+            sentencias SQL; puedes obtener una <literal>Connection</literal> JDBC en cualquier
+            momento llamando a <literal>session.connection()</literal>. Adem&#x00e1;s, la noci&#x00f3;n de
+            operaciones masivas entra en conflicto con el mapeo objeto/relacional en aplicaciones
+            en l&#x00ed;nea orientadas al procesamiento de transacciones. Versiones futuras de Hibernate
+            pueden, sin embargo, proveer funciones de operaci&#x00f3;n masiva especiales. Ver
+            <xref linkend="batch"/> por algunos trucos de operaci&#x00f3;n en lote (batch) posibles.
+            </emphasis>
+        </para>
+
+    </sect1>
+
+    <sect1 id="objectstate-detached" revision="2">
+        <title>Modificando objetos separados</title>
+
+        <para>
+            Muchas aplicaciones necesitan recuperar un objeto en una transacci&#x00f3;n, enviarla
+            a la capa de UI para su manipulaci&#x00f3;n, y entonces salvar los cambios en una nueva
+            transacci&#x00f3;n. Las aplicaciones que usan este tipo de enfoque en un entorno de
+            alta concurrencia usualmente usan datos versionados para asegurar el aislamiento
+            de la unidad de trabajo "larga".
+        </para>
+
+        <para>
+            Hibernate soporta este modelo al proveer re-uni&#x00f3;n de instancias separadas usando
+            los m&#x00e9;todos <literal>Session.update()</literal> o <literal>Session.merge()</literal>:
+        </para>
+
+        <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catId);
+Cat potentialMate = new Cat();
+firstSession.save(potentialMate);
+
+// in a higher layer of the application
+cat.setMate(potentialMate);
+
+// later, in a new session
+secondSession.update(cat);  // update cat
+secondSession.update(mate); // update mate]]></programlisting>
+
+        <para>
+            Si el <literal>Cat</literal> con identificador <literal>catId</literal> ya hubiera
+            sido cargado por <literal>secondSession</literal> cuando la aplicaci&#x00f3;n intent&#x00f3;
+            volver a unirlo, se habr&#x00ed;a lanzado una excepci&#x00f3;n.
+        </para>
+
+        <para>
+            Usa <literal>update()</literal> si no est&#x00e1;s seguro que la sesi&#x00f3;n tenga
+            una instancia ya persistente con el mismo identificador, y <literal>merge()</literal>
+            si quieres fusionar tus modificaciones en cualquier momento sin consideraci&#x00f3;n del
+            estado de la sesi&#x00f3;n. En otras palabras, <literal>update()</literal> es usualmente
+            el primer m&#x00e9;todo que llamar&#x00ed;as en una sesi&#x00f3;n fresca, asegurando que la re-uni&#x00f3;n de
+            tus instancias separadas es la primera operaci&#x00f3;n que se ejecuta.
+        </para>
+
+        <para>
+            La aplicaci&#x00f3;n debe actualizar individualmente las instancias separadas alcanzables
+            por la instancia separada dada llamando a <literal>update()</literal>, si y
+            <emphasis>s&#x00f3;lo</emphasis> si quiere que sus estados sean tambi&#x00e9;n actualizados.
+            Esto puede, por supuesto, ser automatizado usando <emphasis>persistencia transitiva</emphasis>,
+            ver <xref linkend="objectstate-transitive"/>.
+        </para>
+
+        <para>
+            El m&#x00e9;todo <literal>lock()</literal> tambi&#x00e9;n permite a una aplicaci&#x00f3;n reasociar
+            un objeto con una sesi&#x00f3;n nueva. Sin embargo, la instancia separada no puede
+            haber sido modificada!
+        </para>
+
+        <programlisting><![CDATA[//just reassociate:
+sess.lock(fritz, LockMode.NONE);
+//do a version check, then reassociate:
+sess.lock(izi, LockMode.READ);
+//do a version check, using SELECT ... FOR UPDATE, then reassociate:
+sess.lock(pk, LockMode.UPGRADE);]]></programlisting>
+
+        <para>
+            Nota que <literal>lock()</literal> puede ser usado con varios <literal>LockMode</literal>s,
+            ver la documentaci&#x00f3;n de la API y el cap&#x00ed;tulo sobre manejo de transacciones para m&#x00e1;s
+            informaci&#x00f3;n. La re-uni&#x00f3;n no es el &#x00fa;nico caso de uso para <literal>lock()</literal>.
+        </para>
+
+        <para>
+            Se discuten otros modelos para unidades de trabajo largas en <xref linkend="transactions-optimistic"/>.
+        </para>
+
+    </sect1>
+
+    <sect1 id="objectstate-saveorupdate">
+        <title>Detecci&#x00f3;n autom&#x00e1;tica de estado</title>
+
+        <para>
+            Los usuarios de Hibernate han pedido un m&#x00e9;todo de prop&#x00f3;sito general que bien
+            salve una instancia transitoria generando un identificador nuevo, o bien
+            actualice/re&#x00fa;na las instancias separadas asociadas con su identificador actual.
+            El m&#x00e9;todo <literal>saveOrUpdate()</literal> implementa esta funcionalidad.
+        </para>
+
+        <programlisting><![CDATA[// in the first session
+Cat cat = (Cat) firstSession.load(Cat.class, catID);
+
+// in a higher tier of the application
+Cat mate = new Cat();
+cat.setMate(mate);
+
+// later, in a new session
+secondSession.saveOrUpdate(cat);   // update existing state (cat has a non-null id)
+secondSession.saveOrUpdate(mate);  // save the new instance (mate has a null id)]]></programlisting>
+
+        <para>
+            El uso y sem&#x00e1;ntica de <literal>saveOrUpdate()</literal> parece ser confuso para
+            usuarios nuevos. Primeramente, en tanto no est&#x00e9;s intentando usar instancias de una
+            sesi&#x00f3;n en otra sesi&#x00f3;n nueva, no debes necesitar usar <literal>update()</literal>,
+            <literal>saveOrUpdate()</literal>, o <literal>merge()</literal>. Algunas aplicaciones
+            enteras nunca usar&#x00e1;n ninguno de estos m&#x00e9;todos.
+        </para>
+
+        <para>
+            Usualmente <literal>update()</literal> o <literal>saveOrUpdate()</literal> se usan en
+            el siguiente escenario:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    la aplicaci&#x00f3;n carga un objeto en la primera sesi&#x00f3;n
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    el objeto es pasado a la capa de UI
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    se hacen algunas modificaciones al objeto
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    el objeto se pasa abajo de regreso a la capa de negocio
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    la aplicaci&#x00f3;n hace estas modificaciones persistentes llamando
+                    a <literal>update()</literal> en una segunda sesi&#x00f3;n
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            <literal>saveOrUpdate()</literal> hace lo siguiente:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    si el objeto ya es persistente en esta sesi&#x00f3;n, no hace nada
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    si otro objeto asociado con la sesi&#x00f3;n tiene el mismo identificador,
+                    lanza una excepci&#x00f3;n
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    si el objeto no tiene ninguna propiedad identificadora, lo salva llamando a
+                    <literal>save()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    si el identificador del objeto tiene el valor asignado a un objeto reci&#x00e9;n
+                    instanciado, lo salva llamando a <literal>save()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    si el objeto est&#x00e1; versionado (por un <literal>&lt;version&gt;</literal> o
+                    <literal>&lt;timestamp&gt;</literal>), y el valor de la propiedad de versi&#x00f3;n
+                    es el mismo valor asignado a una objeto reci&#x00e9;n instanciado, lo salva llamando
+                    a <literal>save()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    en cualquier otro caso se actualiza el objeto llamando a <literal>update()</literal>
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            y <literal>merge()</literal> es muy diferente:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    si existe una instancia persistente con el mismo identificador asignado actualmente con la
+                    sesi&#x00f3;n, copia el estado del objeto dado en la instancia persistente
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    si no existe ninguna instancia persistente actualmente asociada a la sesi&#x00f3;n,
+                    intente cargarla de la base de datos, o crear una nueva instancia persistente
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    la instancia persistente es devuelta
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    la instancia dada no resulta ser asociada a la sesi&#x00f3;n, permanece separada
+                </para>
+            </listitem>
+        </itemizedlist>
+
+    </sect1>
+
+    <sect1 id="objectstate-deleting" revision="1">
+        <title>Borrando objetos persistentes</title>
+
+        <para>
+            <literal>Session.delete()</literal> quitar&#x00e1; el estado de un objeto de la base de datos.
+            Por supuesto, tu aplicaci&#x00f3;n podr&#x00ed;a tener a&#x00fa;n una referencia a un objeto borrado. Lo mejor
+            es pensar en <literal>delete()</literal> como hacer transitoria una instancia persistente.
+        </para>
+
+        <programlisting><![CDATA[sess.delete(cat);]]></programlisting>
+
+        <para>
+            Puedes borrar los objetos en el orden que gustes, sin riesgo de violaciones
+            de restricci&#x00f3;n de clave for&#x00e1;nea. A&#x00fa;n es posible violar una restricci&#x00f3;n
+            <literal>NOT NULL</literal> sobre una columna clave for&#x00e1;nea borrando objetos
+            en un orden err&#x00f3;neo, por ejemplo, si borras el padre, pero olvidas borrar los
+            hijos.
+        </para>
+
+    </sect1>
+    
+    <sect1 id="objectstate-replicating" revision="1">
+    	<title>Replicando objetos entre dos almac&#x00e9;nes de datos diferentes</title>
+    	
+    	<para>
+            Es ocasionalmente &#x00fa;til ser capaz de tomar un grafo de instancias persistentes
+            y hacerlas persistentes en un almac&#x00e9;n de datos diferente, sin regenerar los valores
+            identificadores.
+    	</para>
+    	
+        <programlisting><![CDATA[//retrieve a cat from one database
+Session session1 = factory1.openSession();
+Transaction tx1 = session1.beginTransaction();
+Cat cat = session1.get(Cat.class, catId);
+tx1.commit();
+session1.close();
+
+//reconcile with a second database
+Session session2 = factory2.openSession();
+Transaction tx2 = session2.beginTransaction();
+session2.replicate(cat, ReplicationMode.LATEST_VERSION);
+tx2.commit();
+session2.close();]]></programlisting>
+
+        <para>
+            El <literal>ReplicationMode</literal> determina c&#x00f3;mo <literal>replicate()</literal>
+            tratar&#x00e1; los conflictos con filas existentes en la base de datos.
+        </para>
+        
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    <literal>ReplicationMode.IGNORE</literal> - ignora el objeto cuando existe una fila
+                    de base de datos con el mismo identificador
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>ReplicationMode.OVERWRITE</literal> - sobrescribe cualquier fila de base de
+                    datos existente con el mismo identificador
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>ReplicationMode.EXCEPTION</literal> - lanza una excepci&#x00f3;n si existe una fila
+                    de base de datos con el mismo identificador
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>ReplicationMode.LATEST_VERSION</literal> - sobrescribe la fila si su n&#x00fa;mero
+                    de versi&#x00f3;n es anterior al n&#x00fa;mero de versi&#x00f3;n del objeto, o en caso contrario ignora el objeto
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Los casos de uso para esta funcionalidad incluyen reconciliar datos ingresados en
+            instancias diferentes de bases de datos, actualizar informaci&#x00f3;n de configuraci&#x00f3;n de
+            sistema durante actualizaciones de producto, deshacer cambios producidos durante
+            transacciones no-ACID y m&#x00e1;s.
+        </para>
+    	
+    </sect1>
+
+    <sect1 id="objectstate-flushing">
+        <title>Limpiando (flushing) la sesi&#x00f3;n</title>
+
+        <para>
+            Cada tanto, la <literal>Session</literal> ejecutar&#x00e1; las sentencias SQL necesarias para
+            sincronizar el estado de la conexi&#x00f3;n JDBC con el estado de los objetos mantenidos en menoria.
+            Este proceso, <emphasis>limpieza (flush)</emphasis>, ocurre por defecto en los siguientes
+            puntos
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    antes de algunas ejecuciones de consulta
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    desde <literal>org.hibernate.Transaction.commit()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    desde <literal>Session.flush()</literal>
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Las sentencias SQL son liberadas en el siguiente orden
+        </para>
+
+        <orderedlist spacing="compact">
+            <listitem>
+                <para>
+                    todas las inserciones de entidades, en el mismo orden que los objetos
+                    correspondientes fueron salvados usando <literal>Session.save()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    todas las actualizaciones de entidades
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    todas los borrados de colecciones
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    todos los borrados, actualizaciones e inserciones de elementos de colecci&#x00f3;n
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    todas las inserciones de colecciones
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    todos los borrados de entidades, en el mismo orden que los objetos
+                    correspondientes fueron borrados usando <literal>Session.delete()</literal>
+                </para>
+            </listitem>
+        </orderedlist>
+
+        <para>
+            (Una excepci&#x00f3;n es que los objetos que usan generaci&#x00f3;n de ID <literal>native</literal>
+            se insertan cuando son salvados.)
+        </para>
+
+        <para>
+            Excepto cuando llamas expl&#x00ed;citamente a <literal>flush()</literal>, no hay en absoluto
+            garant&#x00ed;as sobre <emphasis>cu&#x00e1;ndo</emphasis> la <literal>Session</literal> ejecuta las
+            llamadas JDBC. s&#x00f3;lo sobre el <emphasis>orden</emphasis> en que son ejecutadas. Sin embargo,
+            Hibernate garantiza que los m&#x00e9;todos <literal>Query.list(..)</literal> nunca devolver&#x00e1;n datos
+            a&#x00f1;ejos o err&#x00f3;neos.
+        </para>
+
+        <para>
+            Es posible cambiar el comportamiento por defecto de modo que la limpieza (flush)
+            ocurra menos frecuentemente. La clase <literal>FlushMode</literal> tres modos
+            diferentes: s&#x00f3;lo en tiempo de compromiso (y s&#x00f3;lo cuando se use la API de
+            <literal>Transaction</literal> de Hibernate), limpieza autom&#x00e1;tica usando la rutina
+            explicada, o nunca limpiar a menos que se llame a <literal>flush()</literal>
+            expl&#x00ed;citamente. El &#x00fa;ltimo modo es &#x00fa;til para unidades de trabajo largas, donde una
+            <literal>Session</literal> se mantiene abierta y desconectada por largo tiempo
+            (ver <xref linkend="transactions-optimistic-longsession"/>).
+        </para>
+
+        <programlisting><![CDATA[sess = sf.openSession();
+Transaction tx = sess.beginTransaction();
+sess.setFlushMode(FlushMode.COMMIT); // allow queries to return stale state
+
+Cat izi = (Cat) sess.load(Cat.class, id);
+izi.setName(iznizi);
+
+// might return stale data
+sess.find("from Cat as cat left outer join cat.kittens kitten");
+
+// change to izi is not flushed!
+...
+tx.commit(); // flush occurs]]></programlisting>
+
+        <para>
+            Durante la limpieza, puede ocurrir una excepci&#x00f3;n (por ejemplo, si una operaci&#x00f3;n DML
+            violase una restricci&#x00f3;n). Ya que el manejo de excepciones implica alguna comprensi&#x00f3;n
+            del comportamiento transaccional de Hibernate, lo discutimos en <xref linkend="transactions"/>.
+        </para>
+
+    </sect1>
+
+    <sect1 id="objectstate-transitive">
+        <title>Persistencia transitiva</title>
+
+        <para>
+            Es absolutamente inc&#x00f3;modo dalvar, borrar, o reunir objetos individuales,
+            especialmente si tratas con un grafo de objetos asociados. Un caso com&#x00fa;n es
+            una relaci&#x00f3;n padre/hijo. Considera el siguiente ejemplo:
+        </para>
+
+        <para>
+            Si los hijos en una relaci&#x00f3;n padre/hijo pudieran ser tipificados en valor
+            (por ejemplo, una colecci&#x00f3;n de direcciones o cadenas), sus ciclos de vida
+            depender&#x00ed;an del padre y se requerir&#x00ed;a ninguna otra acci&#x00f3;n para el tratamiento
+            en "cascada" de cambios de estado. Cuando el padre es salvado, los objetos hijo
+            tipificados en valor son salvados tambi&#x00e9;n, cuando se borra el padre, se borran
+            los hijos, etc. Esto funciona incluso para operaciones como el retiro de un
+            hijo de la colecci&#x00f3;n. Hibernate detectar&#x00e1; esto y, ya que los objetos tipificados
+            en valor no pueden tener referencias compartidas, borrar&#x00e1; el hijo de la base
+            de datos.
+        </para>
+
+        <para>
+            Ahora considera el mismo escenario con los objetos padre e hijos siendo entidades,
+            no tipos de valor (por ejemplo, categor&#x00ed;as e &#x00ed;tems, o gatos padre e hijos).
+            Las entidades tienen su propio ciclo de vida, soportan referencias compartidas
+            (de modo que quitar una entidad de una colecci&#x00f3;n no significa que sea borrada),
+            y no hay por defecto ning&#x00fa;n tratamiento en "cascada" de estado de una entidad
+            a otras entidades asociadas. Hibernate no implementa <emphasis>persistencia por
+            alcance</emphasis>.
+        </para>
+
+        <para>
+            Para cada operaci&#x00f3;n b&#x00e1;sica de la sesi&#x00f3;n de Hibernate - incluyendo <literal>persist(), merge(),
+            saveOrUpdate(), delete(), lock(), refresh(), evict(), replicate()</literal> - hay un estilo
+            de cascada correspondiente. Respectivamente, los estilos de cascada se llaman <literal>create, 
+            merge, save-update, delete, lock, refresh, evict, replicate</literal>. Si quieres que una
+            operaci&#x00f3;n sea tratada en cascada a lo largo de una asociaci&#x00f3;n, debes indicar eso en el
+            documento de mapeo. Por ejemplo:
+        </para>
+        
+        <programlisting><![CDATA[<one-to-one name="person" cascade="persist"/>]]></programlisting>
+        
+        <para>
+            Los estilos de cascada pueden combinarse:
+        </para>
+        
+        <programlisting><![CDATA[<one-to-one name="person" cascade="persist,delete,lock"/>]]></programlisting>
+        
+        <para>
+            Puedes incluso usar <literal>cascade="all"</literal> para especificar que <emphasis>todas</emphasis>
+            las operaciones deben ser tratadas en cascada a lo largo de la asociaci&#x00f3;n. El por defecto
+            <literal>cascade="none"</literal> especifica que ninguna operaci&#x00f3;n ser&#x00e1; tratada en cascada.
+        </para>
+        
+        <para>
+            Un estilo de cascada especial, <literal>delete-orphan</literal>, se aplica s&#x00f3;lo a
+            asociaciones uno-a-muchos, e indica que la operaci&#x00f3;n <literal>delete()</literal> debe
+            aplicarse a cualquier objeto hijo que sea quitado de la asociaci&#x00f3;n.
+        </para>
+
+
+        <para>
+            Recomendaciones:
+        </para>
+
+       <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    Usualmente no tiene sentido habilitar el tratamiento en cascada a una asociaci&#x00f3;n
+                    <literal>&lt;many-to-one&gt;</literal> o <literal>&lt;many-to-many&gt;</literal>.
+                    El tratamiento en cascada es frecuentemente &#x00fa;til para las asociaciones
+                    <literal>&lt;one-to-one&gt;</literal> y <literal>&lt;one-to-many&gt;</literal>.
+                    associations.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Si la esperanza de vida de los objetos hijos est&#x00e1; ligada a la eesperanza de
+                    vida del objeto padre, h&#x00e1;zlo un <emphasis>objeto de ciclo de vida</emphasis>
+                    especificando <literal>cascade="all,delete-orphan"</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    En otro caso, puede que no necesites tratamiento en cascada en absoluto. Pero
+                    si piensas que estar&#x00e1;s trabajando frecuentemente con padre e hijos juntos en la
+                    misma transacci&#x00f3;n, y quieres ahorrarte algo de tipeo, considera usar
+                    <literal>cascade="persist,merge,save-update"</literal>.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Mapear una asociaci&#x00f3;n (ya sea una asociaci&#x00f3;n monovaluada, o una colecci&#x00f3;n) con
+            <literal>cascade="all"</literal> marca la asociaci&#x00f3;n como una relaci&#x00f3;n del estilo
+            <emphasis>padre/hijo</emphasis> donde save/update/delete en el padre resulta
+            en save/update/delete del hijo o hijos.
+        </para>
+        <para>
+            Adem&#x00e1;s, una mera referencia a un hijo desde un padre persistente resultar&#x00e1; en
+            un save/update del hijo. Esta met&#x00e1;fora est&#x00e1; incompleta, sin embargo. Un hijo
+            que deje de ser referenciado por su padre <emphasis>no</emphasis> es borrado
+            autom&#x00e1;ticamente, excepto en el caso de una asociaci&#x00f3;n <literal>&lt;one-to-many&gt;</literal>
+            mapeada con <literal>cascade="delete-orphan"</literal>. La sem&#x00e1;ntica precisa de
+            las operaciones en cascada para una relaci&#x00f3;n padre/hijo es:
+        </para>
+
+       <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    Si un padre le es pasado a <literal>persist()</literal>, todos los hijos le son
+                    pasados a <literal>persist()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Si un padre le es pasado a <literal>merge()</literal>, todos los hijos le son
+                    pasados a <literal>merge()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Si un padre le es pasado a <literal>save()</literal>, <literal>update()</literal> o
+                    <literal>saveOrUpdate()</literal>, todos los hijos le son pasados a <literal>saveOrUpdate()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Si un hijo transitorio o separado se vuelve referenciado por un padre
+                    persistente, le es pasado a <literal>saveOrUpdate()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Si un padre es borrado, todos los hijos le son pasados a <literal>delete()</literal>
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Si un hijo deja de ser referenciado por un padre persistente,
+                    <emphasis>no ocurre nada especial</emphasis> - la aplicaci&#x00f3;n debe
+                    borrar expl&#x00ed;citamente el hijo de ser necesario - a menos que
+                    <literal>cascade="delete-orphan"</literal>, en cuyo caso el hijo
+                    "hu&#x00e9;rfano" es borrado.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+    </sect1>
+
+    <sect1 id="objectstate-metadata">
+        <title>Usando metadatos</title>
+
+        <para>
+            Hibernate requiere de un modelo de meta-nivel muy rico de todas las entidades y tipos de valor.
+            De vez en cuando, este modelo es muy &#x00fa;til para la aplicaci&#x00f3;n misma. Por ejemplo, la aplicaci&#x00f3;n
+            podr&#x00ed;a usar los metadatos de Hibernate para implementar un algoritmo "inteligente" de copia
+            en profundidad que entienda qu&#x00e9; objetos deben ser copiados (por ejemplo, tipo de valor mutables)
+            y cu&#x00e1;les no (por ejemplo, tipos de valor inmutables y, posiblemente, entidades asociadas).
+        </para>
+        <para>
+            Hibernate expone los metadatos v&#x00ed;a las interfaces <literal>ClassMetadata</literal> y
+            <literal>CollectionMetadata</literal> y la jerarqu&#x00ed;a <literal>Type</literal>. Las instancias
+            de las interfaces de metadatos pueden obtenerse de <literal>SessionFactory</literal>. 
+        </para>
+
+        <programlisting><![CDATA[Cat fritz = ......;
+ClassMetadata catMeta = sessionfactory.getClassMetadata(Cat.class);
+
+Object[] propertyValues = catMeta.getPropertyValues(fritz);
+String[] propertyNames = catMeta.getPropertyNames();
+Type[] propertyTypes = catMeta.getPropertyTypes();
+
+// get a Map of all properties which are not collections or associations
+Map namedValues = new HashMap();
+for ( int i=0; i<propertyNames.length; i++ ) {
+    if ( !propertyTypes[i].isEntityType() && !propertyTypes[i].isCollectionType() ) {
+        namedValues.put( propertyNames[i], propertyValues[i] );
+    }
+}]]></programlisting>
+        
+    </sect1>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/toolset_guide.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/toolset_guide.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/toolset_guide.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/toolset_guide.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,459 @@
+<chapter id="toolsetguide" revision="2">
+    <title>Gu&#x00ed;a del Conjunto de Herramientas</title>
+
+    <para>
+        La ingenier&#x00ed;a de ida y vuelta con Hibernate es posible usando un conjunto de plugins de Eclipse,
+        herramientas de l&#x00ed;nea de comandos, as&#x00ed; como tareas de Ant.
+    </para>
+
+    <para>
+        Las <emphasis>Herramientas de Hibernate</emphasis> actualmente incluyen plugins para la IDE de
+        Eclipse as&#x00ed; como tareas de Ant para la ingenier&#x00ed;a inversa de bases de datos existentes:
+    </para>
+
+    <itemizedlist>
+        <listitem><para>
+            <emphasis>Editor de Mapeo:</emphasis> Un editor de ficheros de mapeo XML, que soporta autocompleci&#x00f3;n
+            y resaltado de sint&#x00e1;xis. Soporta tambi&#x00e9;n autocompleci&#x00f3;n sem&#x00e1;ntica de nombres de clases y nombres de
+            campos/propiedades, haci&#x00e9;ndolo mucho m&#x00e1;s vers&#x00e1;til que un editor de XML normal.
+        </para></listitem>
+        <listitem><para>
+            <emphasis>Consola:</emphasis> La consola es una nueva vista en Eclipse. Adem&#x00e1;s de la vista de
+            &#x00e1;rbol de tus configuraciones de consola, tienes tambi&#x00e9;n una vista interactiva de tus clases
+            persistentes y sus relaciones. La console te permite ejecutar consultas HQL contra tu base de datos y
+            navegar el resultado directamente en Eclipse.
+        </para></listitem>
+        <listitem><para>
+            <emphasis>Asistentes de Desarrollo:</emphasis> Se proveen muchos asistentes con las herramientas
+            de Eclipse. Puedes usar un asistente para generar r&#x00e1;pidamente ficheros de configuraci&#x00f3;n de Hibernate
+            (cfg.xml), o incluso puedes haceruna ingenier&#x00ed;a inversa completa de un esquema de base de datos existente
+            en ficheros de c&#x00f3;digo de POJO y ficheros de mapeo de Hibernate. El asistente de ingenier&#x00ed;a inversa soporta
+            plantillas personalizables.
+        </para></listitem>
+        <listitem><para>
+            <emphasis>Tareas de Ant:</emphasis>
+        </para></listitem>
+
+    </itemizedlist>
+
+    <para>
+        Por favor refi&#x00e9;rete al paquete <emphasis>Herramientas de Hibernate</emphasis> y su documentaci&#x00f3;n para
+        m&#x00e1;s informaci&#x00f3;n.
+    </para>
+
+    <para>
+        Sin embargo, el paquete principal de Hibernate viene incluyendo una herramienta integrada
+        (puede ser usada incluso "dentro" de Hibernate on-the-fly): <emphasis>SchemaExport</emphasis>
+        tambi&#x00e9;n conocido como <literal>hbm2ddl</literal>.
+    </para>
+
+    <sect1 id="toolsetguide-s1" revision="2">
+        <title>Generaci&#x00f3;n autom&#x00e1;tica de esquemas</title>
+
+        <para>
+            Una utilidad de Hibernate puede generar DDL desde tus ficheros de mapeo. El esquema generado incluye
+            restricciones de integridad referencial (claves primarias y for&#x00e1;neas) para las tablas de entidades y
+            colecciones. Las tablas y secuencias tambi&#x00e9;n son creadas para los generadores de identificadores mapeados.
+        </para>
+        
+        <para>
+            <emphasis>Debes</emphasis> especificar un <literal>Dialecto</literal> SQL v&#x00ed;a la propiedad
+            <literal>hibernate.dialect</literal> al usar esta herramienta, ya que el DDL es altamente espec&#x00ed;fico del
+            vendedor.
+        </para>
+
+        <para>
+            First, customize your mapping files to improve the generated schema.
+        </para>
+
+        <sect2 id="toolsetguide-s1-2" revision="1">
+            <title>Personalizando el esquema</title>
+
+            <para>
+                Muchos elementos de mapeo de Hibernate definen un atributo opcional llamado <literal>length</literal>.
+                Con este atributo puedes establecer el tama&#x00f1;o de una columna. (O, para tipos de datos
+                num&#x00e9;ricos/decimales, la precisi&#x00f3;n.)
+            </para>
+
+            <para>
+                Algunas etiquetas tambi&#x00e9;n aceptan un atributo <literal>not-null</literal> (para generar una restricci&#x00f3;n
+                <literal>NOT NULL</literal> en columnas de tablas) y y un atributo <literal>unique</literal> (para generar
+                restricciones <literal>UNIQUE</literal> en columnas de tablas).
+            </para>
+
+            <para>
+                Algunas etiquetas aceptan un atributo <literal>index</literal> para especificar el nombre de un &#x00ed;ndice
+                para esa columna. Se puede usar un atributo <literal>unique-key</literal> para agrupar columnas en una
+                restricci&#x00f3;n de clave de una sola unidad. Actualmente, el valor especificado del atributo
+                <literal>unique-key</literal> <emphasis>no</emphasis> es usado para nombrar la restricci&#x00f3;n, s&#x00f3;lo para
+                agrupar las columnas en el fichero de mapeo.
+            </para>
+            
+            <para>
+                Ejemplos:
+            </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>
+                Alternativamente, estos elementos aceptan tamb&#x00ed;en un elemento hijo <literal>&lt;column&gt;</literal>.
+                Esto es particularmente &#x00fa;til para tipos multicolumnas:
+            </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>
+                El atributo <literal>sql-type</literal> permite al usuario sobrescribir el mapeo por defecto de
+                tipo Hibernate a tipo de datos SQL.
+            </para>
+            
+            <para>
+                El atributo <literal>check</literal> te permite especificar una comprobaci&#x00f3;n de restricci&#x00f3;n.
+            </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>Resumen</title>
+                <tgroup cols="3">
+                    <colspec colwidth="1*"/>
+                    <colspec colwidth="1*"/>
+                    <colspec colwidth="2.5*"/>
+                    <thead>
+                        <row>
+                            <entry>Atributo</entry>
+                            <entry>Valores</entry>
+                            <entry>Interpretaci&#x00f3;n</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry><literal>length</literal></entry>
+                            <entry>number</entry>
+                            <entry>largo de columna/precisi&#x00f3;n decimal</entry>
+                        </row>
+                        <row>
+                            <entry><literal>not-null</literal></entry>
+                            <entry><literal>true|false</literal></entry>
+                            <entry>especifica que la columna debe ser no nulable</entry>
+                        </row>
+                        <row>
+                            <entry><literal>unique</literal></entry>
+                            <entry><literal>true|false</literal></entry>
+                            <entry>especifica que la columna debe tener una restricci&#x00f3;n de unicidad</entry>
+                        </row>
+                        <row>
+                            <entry><literal>index</literal></entry>
+                            <entry><literal>index_name</literal></entry>
+                            <entry>especifica el nombre de un &#x00ed;ndice (multicolumna)</entry>
+                        </row>
+                        <row>
+                            <entry><literal>unique-key</literal></entry>
+                            <entry><literal>unique_key_name</literal></entry>
+                            <entry>especifica el nombre de una restricci&#x00f3;n de unicidad multicolumna</entry>
+                        </row>
+                        <row>
+                            <entry><literal>foreign-key</literal></entry>
+                            <entry><literal>foreign_key_name</literal></entry>
+                            <entry>
+                                especifica el nombre de la restricci&#x00f3;n de clave for&#x00e1;nea generada por una
+                                asociaci&#x00f3;n, &#x00fa;salo en los elementos de mapeo &lt;one-to-one&gt;, &lt;many-to-one&gt;,
+                                &lt;key&gt;, y &lt;many-to-many&gt;. Nota que los lados
+                                <literal>inverse="true"</literal> no ser&#x00e1;n considerados por
+                                <literal>SchemaExport</literal>.
+                            </entry>
+                        </row>
+                        <row>
+                            <entry><literal>sql-type</literal></entry>
+                            <entry><literal>column_type</literal></entry>
+                            <entry>
+                                sobrescribe el tipo de columna por defecto (s&#x00f3;lo atributo del elemento
+                                <literal>&lt;column&gt;</literal>)
+                            </entry>
+                       </row>
+                       <row>
+                            <entry><literal>check</literal></entry>
+                            <entry>expresi&#x00f3;n SQL</entry>
+                            <entry>
+                                crea una restricci&#x00f3;n de comprobaci&#x00f3;n SQL en columna o  tabla
+                            </entry>
+                       </row>
+                   </tbody>
+                </tgroup>
+            </table>
+            
+            <para>
+                El elemento <literal>&lt;comment&gt;</literal> te permite especificar un comentario para el esquema
+                generado.
+            </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>
+                Esto resulta en una sentencia <literal>comment on table</literal> o <literal>comment on column</literal>
+                en el DDL generado (donde est&#x00e9; soportado).
+            </para>
+
+        </sect2>
+
+        <sect2 id="toolsetguide-s1-3">
+            <title>Ejecutando la herramienta</title>
+
+            <para>
+                La herramienta <literal>SchemaExport</literal> escribe un gui&#x00f3;n DDL a la salida est&#x00e1;ndar y/o
+                ejecuta las sentencias DDL.
+            </para>
+
+            <para>
+                <literal>java -cp </literal><emphasis>classpaths_de_hibernate</emphasis>
+                <literal>org.hibernate.tool.hbm2ddl.SchemaExport</literal> <emphasis>opciones ficheros_de_mapeo</emphasis>
+            </para>
+
+            <table frame="topbot">
+                <title>Opciones de L&#x00ed;nea de Comandos de <literal>SchemaExport</literal></title>
+                <tgroup cols="2">
+                    <colspec colwidth="1.5*"/>
+                    <colspec colwidth="2*"/>
+                    <thead>
+                        <row>
+                            <entry>Opci&#x00f3;n</entry>
+                            <entry>Descripci&#x00f3;n</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry><literal>--quiet</literal></entry>
+                            <entry>no enviar a salida est&#x00e1;ndar el gui&#x00f3;n</entry>
+                        </row>
+                        <row>
+                            <entry><literal>--drop</literal></entry>
+                            <entry>s&#x00f3;lo desechar las tablas</entry>
+                        </row>
+                        <row>
+                            <entry><literal>--text</literal></entry>
+                            <entry>no exportar a la base de datos</entry>
+                        </row>
+                        <row>
+                            <entry><literal>--output=my_schema.ddl</literal></entry>
+                            <entry>enviar la salida del gui&#x00f3;n ddl a un fichero</entry>
+                        </row>
+                        <row>
+                            <entry><literal>--config=hibernate.cfg.xml</literal></entry>
+                            <entry>lee la configuraci&#x00f3;n de Hibernate de un fichero XML</entry>
+                        </row>
+                        <row>
+                            <entry><literal>--properties=hibernate.properties</literal></entry>
+                            <entry>lee las propiedades de base de datos de un fichero</entry>
+                        </row>
+                        <row>
+                            <entry><literal>--format</literal></entry>
+                            <entry>formatea agradablemente el SQL generado en el gui&#x00f3;n</entry>
+                        </row>
+                        <row>
+                            <entry><literal>--delimiter=x</literal></entry>
+                            <entry>establece un delimitador de fin de l&#x00ed;nea para el gui&#x00f3;n</entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+
+            <para>
+                Puedes incluso encajar <literal>SchemaExport</literal> en tu aplicaci&#x00f3;n:
+            </para>
+
+            <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaExport(cfg).create(false, true);]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="toolsetguide-s1-4">
+            <title>Propiedades</title>
+
+            <para>
+                Las propiedades de base de datos pueden especificarse
+            </para>
+
+            <itemizedlist spacing="compact">
+                <listitem>
+                    <para>como propiedades de sistema con <literal>-D</literal><emphasis>&lt;property&gt;</emphasis></para>
+                </listitem>
+                <listitem>
+                    <para>en <literal>hibernate.properties</literal></para>
+                </listitem>
+                <listitem>
+                    <para>en un fichero de propiedades mencionado con <literal>--properties</literal></para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Las propiedades necesarias son:
+            </para>
+
+            <table frame="topbot">
+                <title>Propiedades de Conexi&#x00f3;n de SchemaExport</title>
+                <tgroup cols="2">
+                    <colspec colwidth="1.5*"/>
+                    <colspec colwidth="2*"/>
+                    <thead>
+                        <row>
+                            <entry>Nombre de Propiedad</entry>
+                            <entry>Descripci&#x00f3;n</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                    <row>
+                        <entry><literal>hibernate.connection.driver_class</literal></entry>
+                        <entry>clase del driver jdbc</entry>
+                    </row>
+                    <row>
+                        <entry><literal>hibernate.connection.url</literal></entry>
+                        <entry>url de jdbc</entry>
+                    </row>
+                    <row>
+                        <entry><literal>hibernate.connection.username</literal></entry>
+                        <entry>usuario de base de datos</entry>
+                    </row>
+                    <row>
+                        <entry><literal>hibernate.connection.password</literal></entry>
+                        <entry>contrase&#x00f1;a de usuario</entry>
+                    </row>
+                    <row>
+                        <entry><literal>hibernate.dialect</literal></entry>
+                        <entry>dialecto</entry>
+                    </row>
+                    </tbody>
+                </tgroup>
+            </table>
+
+        </sect2>
+
+        <sect2 id="toolsetguide-s1-5">
+            <title>Usando Ant</title>
+
+            <para>
+                Puedes llamar a <literal>SchemaExport</literal> desde tu gui&#x00f3;n de construcci&#x00f3;n de Ant:
+            </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>Actualizaciones incrementales de esquema</title>
+
+            <para>
+                La herramienta <literal>SchemaUpdate</literal> actualizar&#x00e1; un esquema existente con cambios
+                "incrementales". Nota que <literal>SchemaUpdate</literal> depende fuertemente de la API de metadatos
+                de JDBC, de modo que no funcionar&#x00e1; con todos los drivers JDBC.
+            </para>
+
+            <para>
+                <literal>java -cp </literal><emphasis>classpaths_de_hibernate</emphasis>
+                <literal>org.hibernate.tool.hbm2ddl.SchemaUpdate</literal> <emphasis>opciones ficheros_de_mapeo</emphasis>
+            </para>
+
+            <table frame="topbot">
+                <title>Opciones de L&#x00ed;nea de Comandos de <literal>SchemaUpdate</literal></title>
+                <tgroup cols="2">
+                    <colspec colwidth="1.5*"/>
+                    <colspec colwidth="2*"/>
+                    <thead>
+                        <row>
+                            <entry>Opci&#x00f3;n</entry>
+                            <entry>Descripci&#x00f3;n</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry><literal>--quiet</literal></entry>
+                            <entry>no enviar a salida est&#x00e1;ndar el gui&#x00f3;n</entry>
+                        </row>
+                        <row>
+                            <entry><literal>--properties=hibernate.properties</literal></entry>
+                            <entry>lee las propiedades de base de datos de un fichero</entry>
+                        </row>
+                     </tbody>
+                </tgroup>
+            </table>
+
+            <para>
+                Puedes encajar <literal>SchemaUpdate</literal> en tu aplicaci&#x00f3;n:
+            </para>
+
+            <programlisting><![CDATA[Configuration cfg = ....;
+new SchemaUpdate(cfg).execute(false);]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="toolsetguide-s1-7">
+            <title>Usando Ant para actualizaciones incrementales de esquema</title>
+
+            <para>
+                Puedes llamar a <literal>SchemaUpdate</literal> desde el gui&#x00f3;n de Ant:
+            </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>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/transactions.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/transactions.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/transactions.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/transactions.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,925 @@
+<chapter id="transactions" revision="1">
+    <title>Transacciones y Concurrencia</title>
+
+    <para>
+        El punto m&#x00e1;s importante sobre Hibernate y el control de concurrencia es que muy f&#x00e1;cil
+        de comprender. Hibernate usa directamente conexiones JDBC y recursos JTA sin agregar
+        ning&#x00fa;n comportamiento de bloqueo adicional. Recomendamos altamente que gastes algo de
+        tiempo con la especificaci&#x00f3;n de JDBC, ANSI, y el aislamiento de transacciones de tu sistema
+        de gesti&#x00f3;n de base de datos. Hibernate s&#x00f3;lo a&#x00f1;ade versionado autom&#x00e1;tico pero no bloquea
+        objetos en memoria ni cambia el nivel de aislamiento de tus transacciones de base de datos.
+        B&#x00e1;sicamente, usa Hibernate como usar&#x00ed;as JDBC directo (o JTA/CMT) con tus recursos de base de
+        datos.
+    </para>
+
+    <para>
+        Sin embargo, adem&#x00e1;s del versionado autom&#x00e1;tico, Hibernate ofrece una API (menor) para
+        bloqueo pesimista de filas, usando la sint&#x00e1;xis <literal>SELECT FOR UPDATE</literal>.
+        Esta API se discute m&#x00e1;s adelante en este cap&#x00ed;tulo:
+    </para>
+
+    <para>
+        Comenzamos la discusi&#x00f3;n del control de concurrencia en Hibernate con la granularidad
+        de <literal>Configuration</literal>, <literal>SessionFactory</literal>, y
+        <literal>Session</literal>, as&#x00ed; como la base de datos y las transacciones de aplicaci&#x00f3;n
+        largas.
+    </para>
+
+    <sect1 id="transactions-basics">
+        <title>&#x00c1;mbitos de sesi&#x00f3;n y de transacci&#x00f3;n</title>
+
+        <para>
+            Una <literal>SessionFactory</literal> es un objeto seguro entre hebras caro-de-crear
+            pensado para ser compartido por todas las hebras de la aplicaci&#x00f3;n. Es creado una sola vez,
+            usualmente en el arranque de la aplicaci&#x00f3;n, a partir de una instancia de <literal>Configuration</literal>.
+        </para>
+
+        <para>
+            Una <literal>Session</literal> es un objeto barato, inseguro entre hebras que debe
+            ser usado una sola vez, para un solo proceso de negocio, una sola unidad de trabajo,
+            y luego descartado. Una <literal>Session</literal> no obtendr&#x00e1; una <literal>Connection</literal>
+            JDBC (o un <literal>Datasource</literal>) a menos que sea necesario, de modo que puedas
+            abrir y cerrar seguramente una <literal>Session</literal> incluso si no est&#x00e1;s seguro
+            que se necesitar&#x00e1; acceso a los datos para servir una petici&#x00f3;n en particular. (Esto se
+            vuelve importante en cuanto est&#x00e9;s implementando alguno de los siguientes patrones usando
+            intercepci&#x00f3;n de peticiones).
+        </para>
+
+        <para>
+            Para completar este cuadro tienes que pensar tambi&#x00e9;n en las transacciones de base de
+            datos. Una transacci&#x00f3;n de base de datos tiene que ser tan corta como sea posible, para
+            reducir la contenci&#x00f3;n de bloqueos en la base de datos. Las transacciones largas de base de
+            datos prevendr&#x00e1;n a tu aplicaci&#x00f3;n de escalar a una carga altamente concurrente.
+        </para>
+
+        <para>
+            &#x00bf;Qu&#x00e9; es el &#x00e1;mbito de una unidad de trabajo? &#x00bf;Puede una sola <literal>Session</literal> de Hibernate
+            extenderse a trav&#x00e9;s de varias transacciones de base de datos o es &#x00e9;sta una relaci&#x00f3;n uno-a-uno
+            de &#x00e1;mbitos? &#x00bf;Cu&#x00e1;ndo debes abrir y cerrar una <literal>Session</literal> y c&#x00f3;mo demarcas los
+            l&#x00ed;mites de la transacci&#x00f3;n de base de datos?
+        </para>
+
+        <sect2 id="transactions-basics-uow">
+            <title>Unidad de trabajo</title>
+
+            <para>
+                Primero, no uses el antipatr&#x00f3;n <emphasis>sesi&#x00f3;n-por-operaci&#x00f3;n</emphasis>, esto es,
+                &#x00a1;no abras y cierres una <literal>Session</literal> para cada simple llamada a la base
+                de datos en una sola hebra! Por supuesto, lo mismo es verdad para transacciones de base de
+                datos. Las llamadas a base de datos en una aplicaci&#x00f3;n se hacen usando una secuencia
+                prevista, que est&#x00e1;n agrupadas dentro de unidades de trabajo at&#x00f3;micas. (Nota que esto
+                tambi&#x00e9;n significa que el auto-commit despu&#x00e9;s de cada una de las sentencias SQL es in&#x00fa;til
+                en una aplicaci&#x00f3;n, este modo est&#x00e1; pensado para trabajo ad-hoc de consola SQL.
+                Hibernate deshabilita, o espera que el servidor de aplicaciones lo haga, el modo
+                auto-commit inmediatamente.)
+            </para>
+
+            <para>
+                El patr&#x00f3;n m&#x00e1;s com&#x00fa;n en una aplicaci&#x00f3;n mutiusuario cliente/servidor es
+                <emphasis>sesi&#x00f3;n-por-petici&#x00f3;n</emphasis>. En este modelo, una petici&#x00f3;n del cliente
+                es enviada al servidor (en donde se ejecuta la capa de persistencia de Hibernate),
+                se abre una nueva <literal>Session</literal> de Hibernate, y todas las operaciones
+                de base de datos se ejecutan en esta unidad de trabajo. Una vez completado el trabajo
+                (y se ha preparado la respuesta para el cliente) la sesi&#x00f3;n es limpiada y cerrada.
+                Podr&#x00ed;as usar una sola transacci&#x00f3;n de base de datos para servir a petici&#x00f3;n del cliente,
+                comenz&#x00e1;ndola y comprometi&#x00e9;ndola cuando abres y cierras la <literal>Session</literal>.
+                La relaci&#x00f3;n entre las dos es uno-a-uno y este modelo es a la medida perfecta de muchas
+                aplicaciones.
+            </para>
+
+            <para>
+                El desaf&#x00ed;o yace en la implementaci&#x00f3;n: no s&#x00f3;lo tienen que comenzarse y terminarse correctamente
+                la <literal>Session</literal> y la transacci&#x00f3;n, sino que adem&#x00e1;s tienen que estar accesibles
+                para las operaciones de acceso a datos. La demarcaci&#x00f3;n de una unidad de trabajo se implementa
+                idealmente usando un interceptor que se ejecuta cuando una petici&#x00f3;n llama al servidor y anter que
+                la respuesta sea enviada (es decir, un <literal>ServletFilter</literal>). Recomendamos ligar la
+                <literal>Session</literal> a la hebra que atiende la petici&#x00f3;n, usando una variable
+                <literal>ThreadLocal</literal>. Esto permite un f&#x00e1;cil acceso (como acceder a una variable static)
+                en t&#x00f3;do el c&#x00f3;digo que se ejecuta en esta hebra. Dependiendo del mecanismo de demarcaci&#x00f3;n de
+                transacciones de base de datos que elijas, podr&#x00ed;as mantener tambi&#x00e9;n el contexto de la transacci&#x00f3;n
+                en una variable <literal>ThreadLocal</literal>. Los patrones de implementaci&#x00f3;n para esto son
+                conocidos como <emphasis>Sesi&#x00f3;n Local de Hebra (ThreadLocal Session)</emphasis> y
+                <emphasis>Sesi&#x00f3;n Abierta en Vista (Open Session in View)</emphasis>. Puedes extender f&#x00e1;cilmente
+                la clase de ayuda <literal>HibernateUtil</literal> mostrada anteriormente para encontrar
+                una forma de implementar un interceptor e instalarlo en tu entorno. Ver el sitio web de Hibernate
+                para consejos y ejemplos.
+             </para>
+
+        </sect2>
+
+        <sect2 id="transactions-basics-apptx">
+            <title>Transacciones de aplicaci&#x00f3;n</title>
+
+            <para>
+                El patr&#x00f3;n sesi&#x00f3;n-por-petici&#x00f3;n no es el &#x00fa;nico concepto &#x00fa;til que puedes usar para dise&#x00f1;ar unidades
+                de trabajo. Muchos procesos de negocio requiere una serie completa de interacciones con el
+                usuario intercaladas con accesos a base de datos. En aplicaciones web y de empresa no es aceptable
+                que una transacci&#x00f3;n de base de datos se extienda a trav&#x00e9;s de la interacci&#x00f3;n de un usuario.
+                Considera el siguiente ejemplo:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Se abre la primera pantalla de un di&#x00e1;logo, los datos vistos por el usuario han sido
+                        cargados en una <literal>Session</literal> y transacci&#x00f3;n de base de datos particular.
+                        El usuario es libre de modificar los objetos.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        El usuario hace click en "Salvar" despu&#x00e9;s de 5 minutos y espera que sus modificaciones
+                        sean hechas persistentes. Tambi&#x00e9;n espera que &#x00e9;l sea la &#x00fa;nica persona editando esta
+                        informaci&#x00f3;n y que no puede ocurrir ninguna modificaci&#x00f3;n en conflicto.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Llamamos a esto unidad de trabajo, desde el punto de vista del usuario, una larga
+                <emphasis>transacci&#x00f3;n de aplicaci&#x00f3;n</emphasis> ejecut&#x00e1;ndose. Hay muchas formas en
+                que puedes implementar esto en tu aplicaci&#x00f3;n.
+            </para>
+
+            <para>
+                Una primera implementaci&#x00f3;n ingenua podr&#x00ed;a mantener abierta la <literal>Session</literal>
+                y la transacci&#x00f3;n de base de datos durante el tiempo de pensar del usuario, con bloqueos
+                tomados en la base de datos para prevenir la modificaci&#x00f3;n concurrente, y para garantizar
+                aislamiento y atomicidad. Esto es, por supuesto, un antipatr&#x00f3;n, ya que la contenci&#x00f3;n de
+                bloqueo no permitir&#x00ed;a a la aplicaci&#x00f3;n escalar con el n&#x00fa;mero de usuarios concurrentes.
+            </para>
+
+            <para>
+                Claramente, tenemos que usar muchas transacciones de base de datos para implementar la transacci&#x00f3;n
+                de aplicaci&#x00f3;n. En este caso, mantener el aislamiento de los procesos de negocio se vuelve una
+                responsabilidad parcial de la capa de aplicaci&#x00f3;n. Una sola transacci&#x00f3;n de aplicaci&#x00f3;n usualmente
+                abarca varias transacciones de base de datos. Ser&#x00e1; at&#x00f3;mica si s&#x00f3;lo una de estas transacciones de
+                base de datos (la &#x00fa;ltima) almacena los datos actualizados, todas las otras simplemente leen datos
+                (por ejemplo, en un di&#x00e1;logo estilo-asistente abarcando muchos ciclos petici&#x00f3;n/respuesta).
+                Esto es m&#x00e1;s f&#x00e1;cil de implementar de lo que suena, especialmente si usas las funcionalidades de
+                Hibernate:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <emphasis>Versionado Autom&#x00e1;tico</emphasis> - Hibernate puede llevar un control autom&#x00e1;tico de
+                        concurrencia optimista por ti, puede detectar autom&#x00e1;ticamente si una modificaci&#x00f3;n concurrente
+                        ha ocurrido durante el tiempo de pensar del usuario.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis>Objetos Separados</emphasis> - Si decides usar el ya discutido patr&#x00f3;n
+                        de <emphasis>sesi&#x00f3;n-por-petici&#x00f3;n</emphasis>, todas las instancias cargadas estar&#x00e1;n
+                        en estado separado durante el tiempo de pensar del usuario. Hibernate te permite
+                        volver a unir los objetos y hacer persistentes las modificaciones. El patr&#x00f3;n se
+                        llama <emphasis>sesi&#x00f3;n-por-petici&#x00f3;n-con-objetos-separados</emphasis>. Se usa
+                        versionado autom&#x00e1;tico para aislar las modificaciones concurrentes. 
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <emphasis>Sesi&#x00f3;n Larga</emphasis> - La <literal>Session</literal> de Hibernate puede ser
+                        desconectada de la conexi&#x00f3;n JDBC subyacente despu&#x00e9;s que se haya sido comprometida la
+                        transacci&#x00f3;n de base de datos, y reconectada cuando ocurra una nueva petici&#x00f3;n del cliente.
+                        Este patr&#x00f3;n es conocido como <emphasis>sesi&#x00f3;n-por-transacci&#x00f3;n-de-aplicaci&#x00f3;n</emphasis>
+                        y hace la re-uni&#x00f3;n innecesaria. Para aislar las modificaciones concurrentes se usa el
+                        versionado autom&#x00e1;tico.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                Tanto <emphasis>sesi&#x00f3;n-por-petici&#x00f3;n-con-objetos-separados</emphasis> como
+                <emphasis>sesi&#x00f3;n-por-transacci&#x00f3;n-de-aplicaci&#x00f3;n</emphasis>, ambas tienen 
+                ventajas y desventajas, las discutimos m&#x00e1;s adelante en este cap&#x00ed;tulo en el contexto
+                del control optimista de concurrencia.
+            </para>
+
+        </sect2>
+
+        <sect2 id="transactions-basics-identity">
+            <title>Considerando la identidad del objeto</title>
+
+            <para>
+                Una aplicaci&#x00f3;n puede acceder concurrentemente a el mismo estado persistente en dos
+                <literal>Session</literal>s diferentes. Sin embargo, una instancia de una clase
+                persistente nunca se comparte entre dos instancias de <literal>Session</literal>.
+                Por lo tanto existen dos nociones diferentes de identidad:
+            </para>
+
+            <variablelist spacing="compact">
+                <varlistentry>
+                    <term>Identidad de Base de Datos</term>
+                    <listitem>
+                        <para>
+                            <literal>foo.getId().equals( bar.getId() )</literal>
+                        </para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>Identidad JVM</term>
+                    <listitem>
+                        <para>
+                            <literal>foo==bar</literal>
+                        </para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+
+            <para>
+                Entonces para objetos unidos a una <literal>Session</literal> <emphasis>en particular</emphasis>
+                (es decir en el &#x00e1;mbito de una <literal>Session</literal>) las dos nociones son equivalentes, y
+                la identidad JVM para la identidad de base de datos est&#x00e1; garantizada por Hibernate. Sin embargo,
+                mientras la aplicaci&#x00f3;n acceda concurrentemente al "mismo" (identidad persistente) objeto de negocio
+                en dos sesiones diferentes, las dos instancias ser&#x00e1;n realmente "diferentes" (identidad JVM).
+                Los conflictos se resuelven (con versionado autom&#x00e1;tico) en tiempo de limpieza (flush) usando un
+                enfoque optimista.
+            </para>
+
+            <para>
+                Este enfoque deja que Hibernate y la base de datos se preocupen sobre la concurrencia. Adem&#x00e1;s
+                provee la mejor escalabilidad, ya que garantizando la identidad un unidades de trabajo monohebra
+                no se necesitan bloqueos caros u otros medios de sincronizaci&#x00f3;n. La aplicaci&#x00f3;n nunca necesita
+                sincronizar sobre ning&#x00fa;n objeto de negocio, siempre que se apegue a una sola hebra por
+                <literal>Session</literal>. Dentro de una <literal>Session</literal> la aplicaci&#x00f3;n puede usar
+                con seguridad <literal>==</literal> para comparar objetos.
+            </para>
+
+            <para>
+                Sin embargo, una aplicaci&#x00f3;n que usa <literal>==</literal> fuera de una <literal>Session</literal>,
+                podr&#x00ed;a ver resultados inesperados. Esto podr&#x00ed;a ocurrir incluso en sitios algo inesperados,
+                por ejemplo, si pones dos instancias separadas dentro del mismo <literal>Set</literal>.
+                Ambas podr&#x00ed;an tener la misma identidad de base de datos (es decir, representar la misma fila),
+                pero la identidad JVM, por definici&#x00f3;n, no est&#x00e1; garantizada para las instancias en estado separado.
+                El desarrollador tiene que sobrescribir los m&#x00e9;todos <literal>equals()</literal> y
+                <literal>hashCode()</literal> en las clases persistentes e implementar su propia noci&#x00f3;n de igualdad
+                de objetos. Hay una advertencia: Nunca uses el identificador de base de datos para implementar
+                la igualdad, usa una clave de negocio, una combinaci&#x00f3;n de atributos &#x00fa;nicos, usualmente inmutables.
+                El identificador de base de datos cambiar&#x00e1; si un objeto transitorio es hecho persistente.
+                Si la instancia transitoria (usualmente junta a instancias separadas) es mantenida en un
+                <literal>Set</literal>, cambiar el c&#x00f3;digo hash rompe el contrato del <literal>Set</literal>.
+                Los atributos para las claves de negocio no tienen que ser tan estables como las claves primarias
+                de base de datos, s&#x00f3;lo tienes que garantizar estabilidad en tanto los objetos est&#x00e9;n en el mismo
+                <literal>Set</literal>. Mira el sitio web de Hibernate para una discusi&#x00f3;n m&#x00e1;s cuidadosa de este
+                tema. Nota tambi&#x00e9;n que &#x00e9;ste no es un tema de Hibernate, sino simplemente c&#x00f3;mo la identidad y la igualdad
+                de los objetos Java tiene que ser implementada.
+            </para>
+
+        </sect2>
+
+        <sect2 id="transactions-basics-issues">
+            <title>Temas comunes</title>
+
+             <para>
+                 Nunca uses los antipatrones <emphasis>sesi&#x00f3;n-por-sesi&#x00f3;n-de-usuario</emphasis> o
+                 <emphasis>sesi&#x00f3;n-por-aplicaci&#x00f3;n</emphasis> (por supuesto, hay raras excepciones a esta
+                 regla). Nota que algunis de los siguientes temas podr&#x00ed;an tambi&#x00e9;n aparecer con los patrones
+                 recomendados. Aseg&#x00fa;rate que entiendes las implicaciones antes de tomar una decisi&#x00f3;n de
+                 dise&#x00f1;o:
+             </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Una <literal>Session</literal> no es segura entre hebras. Las cosas que se suponen
+                        que funcionan concurrentemente, como peticiones HTTP, beans de sesi&#x00f3;n, o workers de
+                        Swing, provocar&#x00e1;n condiciones de competencia si una instancia de <literal>Session</literal> 
+                        fuese compartida. Si guardas tu <literal>Session</literal> de Hibernate en tu
+                        <literal>HttpSession</literal> (discutido m&#x00e1;s adelante), debes considerar sincronizar
+                        el acceso a tu sesi&#x00f3;n HTTP. De otro modo, un usuario que hace click lo suficientemente
+                        r&#x00e1;pido puede llegar a usar la misma <literal>Session</literal> en dos hebras ejecut&#x00e1;ndose
+                        concurrentemente.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Una excepci&#x00f3;n lanzada por Hibernate significa que tienes que deshacer (rollback) tu
+                        transacci&#x00f3;n de base de datos y cerrar la <literal>Session</literal> inmediatamente
+                        (discutido en m&#x00e1;s detalle luego). Si tu <literal>Session</literal> est&#x00e1; ligada a la
+                        aplicaci&#x00f3;n, tienes que parar la aplicaci&#x00f3;n. Deshacer (rollback) la transacci&#x00f3;n de base
+                        de datos no pone a tus objetos de vuelta al estado en que estaban al comienzo de la
+                        transacci&#x00f3;n. Esto significa que el estado de la base de datos y los objetos de negocio
+                        quedan fuera de sincron&#x00ed;a. Usualmente esto no es un problema, pues las excepciones no
+                        son recuperables y tienes que volver a comenzar despu&#x00e9;s del rollback de todos modos.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        La <literal>Session</literal> pone en cach&#x00e9; todo objeto que est&#x00e9; en estado persistente
+                        (vigilado y chequeado por estado sucio por Hibernate). Esto significa que crece sin
+                        fin hasta que obtienes una OutOfMemoryException, si la mantienes abierta por un largo
+                        tiempo o simplemente cargas demasiados datos. Una soluci&#x00f3;n para esto es llamar a
+                        <literal>clear()</literal> y <literal>evict()</literal> para gestionar el cach&#x00e9; de la
+                        <literal>Session</literal>, pero probalemente debas considerar un procedimiento almacenado
+                        si necesitas operaciones de datos masivas. Se muestran algunas soluciones  en
+                        <xref linkend="batch"/>. Mantener una <literal>Session</literal> abierta por la duraci&#x00f3;n
+                        de una sesi&#x00f3;n de usuario significa tambi&#x00e9;n una alta probabilidad de datos a&#x00f1;ejos.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="transactions-demarcation">
+        <title>Demarcaci&#x00f3;n de la transacci&#x00f3;n de base de datos</title>
+
+        <para>
+            Los l&#x00ed;mites de las transacciones de base de datos (o sistema) son siempre necesarios. Ninguna comunicaci&#x00f3;n
+            con la base de datos puede darse fuera de una transacci&#x00f3;n de base de datos (esto parece confundir muchos
+            desarrolladores acostumbrados al modo auto-commit). Siempre usa l&#x00ed;mites de transacci&#x00f3;n claros, incluso
+            para las operaciones de s&#x00f3;lo lectura. Dependiendo del nivel de aislamiento y las capacidades de base de
+            datos, esto podr&#x00ed;a o no ser requerido, pero no hay un merma si siempre demarcas expl&#x00ed;citamente
+            las transacciones.
+        </para>
+
+        <para>
+            Una aplicaci&#x00f3;n Hibernate puede ejecutarse en entornos no manejados (es decir, como independiente,
+            Web simple, o aplicaciones Swing) y entornos manejados J2EE. En un entorno no manejado, Hibernate es
+            usualmente responsable de su propio pool de conexiones de base de datos. El desarrollador de aplicaciones
+            tiene que establecer manualmente los l&#x00ed;mites de transacci&#x00f3;n, en otras palabras, hacer begin, commit, o
+            rollback las transacciones de base de datos por s&#x00ed; mismo. Un entorno manejado usualmente provee transacciones
+            gestionadas por contenedor, con el ensamble de transacci&#x00f3;n definido declarativamente en descriptores de
+            despliegue de beans de sesi&#x00f3;n EJB, por ejemplo. La demarcaci&#x00f3;n program&#x00e1;tica de transacciones no es m&#x00e1;s
+            necesario, incluso limpiar (flush) la <literal>Session</literal> es hecho autom&#x00e1;ticamente.
+        </para>
+
+        <para>
+            Sin embargo, frecuentemente es deseable mantener portable tu capa de persistencia. Hibernate ofrece
+            una API de envoltura llamada <literal>Transaction</literal> que se traduce al sistema de transacciones
+            nativo de tu entorno de despliegue. Esta API es realmente opcional, pero recomendamos fuertemente su uso
+            salvo que est&#x00e9;s en un bean de sesi&#x00f3;n CMT.
+        </para>
+
+        <para>
+            Usualmente, finalizar una <literal>Session</literal> implica cuatro fases distintas:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    limpiar (flush) la sesi&#x00f3;n
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    comprometer la transacci&#x00f3;n
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    cerrar la sesi&#x00f3;n
+                </para>
+            </listitem>
+            <listitem>
+                <para> 
+                    manejar excepciones
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Limpiar la sesi&#x00f3;n ha sido discutido anteriormente, tendremos ahora una mirada m&#x00e1;s de cerca
+            a la demarcaci&#x00f3;n de transacciones y manejo de excepciones en sendos entornos manejado y no manejados.
+        </para>
+
+
+        <sect2 id="transactions-demarcation-nonmanaged">
+            <title>Entorno no manejado</title>
+
+            <para>
+                Si una capa de persistencia Hibernate se ejecuta en un entorno no manejado, las conexiones
+                de base de datos son manejadas usualmente por el mecanismo de pooling de Hibernate. El idioma
+                manejo de sesi&#x00f3;n/transacci&#x00f3;n se ve as&#x00ed;:
+            </para>
+
+            <programlisting><![CDATA[//Non-managed environment idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+    tx = sess.beginTransaction();
+
+    // do some work
+    ...
+
+    tx.commit();
+}
+catch (RuntimeException e) {
+    if (tx != null) tx.rollback();
+    throw e; // or display error message
+}
+finally {
+    sess.close();
+}]]></programlisting>
+
+            <para>
+                No tienes que limpiar con <literal>flush()</literal> la <literal>Session</literal> expl&#x00ed;citamente -
+                la llamada a <literal>commit()</literal> autom&#x00e1;ticamente dispara la sincronizaci&#x00f3;n.
+            </para>
+
+            <para>
+                Una llamada a <literal>close()</literal> marca el fin de una sesi&#x00f3;n. La principal implicaci&#x00f3;n
+                de <literal>close()</literal> es que la conexi&#x00f3;n JDBC ser&#x00e1; abandonada por la sesi&#x00f3;n.
+            </para>
+
+            <para>
+                Este c&#x00f3;digo Java es portable y se ejecuta tanto en entornos no manejados como en entornos JTA.
+            </para>
+
+            <para>
+                Muy probablemente nunca veas este idioma en c&#x00f3;digo de negocio en una aplicaci&#x00f3;n normal;
+                las excepciones fatales (sistema) deben siempre ser capturadas en la "cima". En otras palabras,
+                el c&#x00f3;digo que ejecuta las llamadas de Hibernate (en la capa de persistencia) y el c&#x00f3;digo que
+                maneja <literal>RuntimeException</literal> (y usualmente s&#x00f3;lo puede limpiar y salir) est&#x00e1;n en
+                capas diferentes. Esto puede ser un desaf&#x00ed;o de dise&#x00f1;arlo t&#x00fa; mismo y debes usar los servicios
+                de contenedor J2EE/EJB en cuanto estuviesen disponibles. El manejo de excepciones se dicute
+                m&#x00e1;s adelante en este cap&#x00ed;tulo.
+            </para>
+
+           <para>
+                Nota que debes seleccionar <literal>org.hibernate.transaction.JDBCTransactionFactory</literal>
+                (que es el por defecto).
+            </para>
+            
+        </sect2>
+
+        <sect2 id="transactions-demarcation-jta">
+            <title>Usando JTA</title>
+
+            <para>
+                Si tu capa de persistencia se ejecuta en un servidor de aplicaciones (por ejemplo, detr&#x00e1;s
+                de beans de sesi&#x00f3;n EJB), cada conexi&#x00f3;n de datasource obtenida por Hibernate ser&#x00e1; parte
+                autom&#x00e1;ticamente de la transacci&#x00f3;n JTA global. Hibernate ofrece dos estrategias para esta
+                integraci&#x00f3;n.
+            </para>
+
+            <para>
+                Si usas transacciones gestionadas-por-bean (BMT) Hibernate le dir&#x00e1; al servidor de aplicaciones
+                que comience y finalice una transacci&#x00f3;n BMT si usas la API de <literal>Transaction</literal>.
+                De modo que, el c&#x00f3;digo de gesti&#x00f3;n de la transacci&#x00f3;n es id&#x00e9;ntico al de un entorno no manejado.
+            </para>
+            
+           <programlisting><![CDATA[// BMT idiom
+Session sess = factory.openSession();
+Transaction tx = null;
+try {
+    tx = sess.beginTransaction();
+
+    // do some work
+    ...
+
+    tx.commit();
+}
+catch (RuntimeException e) {
+    if (tx != null) tx.rollback();
+    throw e; // or display error message
+}
+finally {
+    sess.close();
+}]]></programlisting>
+
+            <para>
+                Con CMT, la demarcaci&#x00f3;n de la transacci&#x00f3;n se hace en descriptores de despliegue de beans de sesi&#x00f3;n,
+                no program&#x00e1;ticamente. Si no quieres limpiar (flush) y cerrar manualmente la <literal>Session</literal>
+                por ti mismo, solamente establece <literal>hibernate.transaction.flush_before_completion</literal> a
+                <literal>true</literal>, <literal>hibernate.connection.release_mode</literal> a
+                <literal>after_statement</literal> o <literal>auto</literal> y
+                <literal>hibernate.transaction.auto_close_session</literal> a <literal>true</literal>. Hibernate
+                limpiar&#x00e1; y cerrar&#x00e1; entonces autom&#x00e1;ticamente la <literal>Session</literal> para ti. Lo &#x00fa;nico que resta
+                es deshacer (rollback) la transacci&#x00f3;n cuando ocurra una excepci&#x00f3;n. Afortunadamente, en un bean CMT,
+                incluso esto ocurre autom&#x00e1;ticamente, ya que una <literal>RuntimeException</literal> no manejada
+                disparada por un m&#x00e9;todo de un bean de sesi&#x00f3;n le dice al contenedor que ponga a deshacer la transacci&#x00f3;n
+                global. <emphasis>Esto significa que, en CMT, no necesitas usar en absoluto la API de
+                <literal>Transaction</literal> de Hibernate.</emphasis>
+            </para>
+
+            <para>
+                Nota que debes elegir <literal>org.hibernate.transaction.JTATransactionFactory</literal> en un
+                bean de sesi&#x00f3;n BMT, y <literal>org.hibernate.transaction.CMTTransactionFactory</literal> en un
+                bean de sesi&#x00f3;n CMT, cuando configures la f&#x00e1;brica de transacciones de Hibernate. Recuerda adem&#x00e1;s
+                establecer <literal>org.hibernate.transaction.manager_lookup_class</literal>.
+            </para>
+
+            <para>
+                Si trabajas en un entorno CMT, y usas limpieza (flushing) y cierre autom&#x00e1;ticos de la sesi&#x00f3;n,
+                podr&#x00ed;as querer tambi&#x00e9;n usar la misma sesi&#x00f3;n en diferentes partes de tu c&#x00f3;digo. T&#x00ed;picamente,
+                en un entorno no manejado, usar&#x00ed;as una variable <literal>ThreadLocal</literal> para tener la sesi&#x00f3;n,
+                pero una sola petici&#x00f3;n de EJB puede ejecutarse en diferentes hebras (por ejemplo, un bean de sesi&#x00f3;n
+                llamando a otro bean de sesi&#x00f3;n). Si no quieres molestarte en pasar tu <literal>Session</literal>
+                por alrededor, la <literal>SessionFactory</literal> provee el m&#x00e9;todo
+                <literal>getCurrentSession()</literal>, que devuelve una sesi&#x00f3;n que est&#x00e1; pegada al contexto de
+                transacci&#x00f3;n JTA. &#x00a1;Esta es la forma m&#x00e1;s f&#x00e1;cil de integrar Hibernate en una aplicaci&#x00f3;n!
+                La sesi&#x00f3;n "actual" siempre tiene habilitados limpieza, cierre y liberaci&#x00f3;n de conexi&#x00f3;n autom&#x00e1;ticos
+                (sin importar la configuraci&#x00f3;n de las propiedades anteriores). Nuestra idioma de gesti&#x00f3;n de
+                sesi&#x00f3;n/transacci&#x00f3;n se reduce a:
+            </para>
+
+           <programlisting><![CDATA[// CMT idiom
+Session sess = factory.getCurrentSession();
+
+// do some work
+...
+
+]]></programlisting>
+
+            <para>
+                En otras palabras, todo lo que tienes que hacer en un entorno manejado, es llamar a 
+                <literal>SessionFactory.getCurrentSession()</literal>, hacer tu trabajo de acceso a datos,
+                y dejar el resto al contenedor. Los l&#x00ed;mites de transacci&#x00f3;n se establecen declarativamente
+                en los descriptores de despliegue de tu bean de sesi&#x00f3;n. El ciclo de vida de la sesi&#x00f3;n es
+                manejado completamente por Hibernate.
+            </para>
+            
+            <para>
+                Existe una advertencia al uso del modo de liberaci&#x00f3;n de conexi&#x00f3;n <literal>after_statement</literal>.
+                Debido a una limitaci&#x00f3;n tonta de la especificaci&#x00f3;n de JTA, no es posible para Hibernate
+                limpiar autom&#x00e1;ticamente ning&#x00fa;n <literal>ScrollableResults</literal> no cerrado ni
+                instancias de <literal>Iterator</literal> devueltas por  <literal>scroll()</literal> o
+                <literal>iterate()</literal>. <emphasis>Debes</emphasis> liberar el cursor de base de datos
+                subyacente llamando a <literal>ScrollableResults.close()</literal> o
+                <literal>Hibernate.close(Iterator)</literal> expl&#x00ed;citamente desde un bloque <literal>finally</literal>.
+                (Por supuesto, la mayor&#x00ed;a de las aplicaciones pueden evitarlo f&#x00e1;cilmente no usando en absoluto ning&#x00fa;n
+                <literal>scroll()</literal> o <literal>iterate()</literal> desde el c&#x00f3;digo CMT.)
+            </para>
+
+        </sect2>
+
+        <sect2 id="transactions-demarcation-exceptions">
+            <title>Manejo de excepciones</title>
+
+            <para>
+                Si la <literal>Session</literal> lanza una excepci&#x00f3;n (incluyendo cualquier
+                <literal>SQLException</literal>), debes inmediatamente deshacer (rollback) la
+                transacci&#x00f3;n de base de datos, llamar a <literal>Session.close()</literal> y
+                descartar la instancia de <literal>Session</literal>. Ciertos m&#x00e9;todos de
+                <literal>Session</literal> <emphasis>no</emphasis> dejar&#x00e1;n la sesi&#x00f3;n en un
+                estado consistente. Ninguna excepci&#x00f3;n lanzada por Hibernate puede ser tratada
+                como recuperable. Aseg&#x00fa;rate que la <literal>Session</literal> sea cerrada llamando
+                a <literal>close()</literal> en un bloque <literal>finally</literal>.
+            </para>
+
+            <para>
+                La <literal>HibernateException</literal>, que envuelve la mayor&#x00ed;a de los errores que
+                pueden ocurrir en la capa de persistencia de Hibernate, en una excepci&#x00f3;n no chequeada
+                (no lo era en versiones anteriores de Hibernate). En nuestra opini&#x00f3;n, no debemos forzar
+                al desarrollador de aplicaciones a capturar una excepci&#x00f3;n irrecuperable en una capa baja.
+                En la mayor&#x00ed;a de los sistemas, las excepciones no chequeadas y fatales son manejadas
+                en uno de los primeros cuadros de la pila de llamadas a m&#x00e9;todos (es decir, en las capas
+                m&#x00e1;s altas) y se presenta un mensaje de error al usuario de la aplicaci&#x00f3;n (o se toma alguna
+                otra acci&#x00f3;n apropiada). Nota que Hibernate podr&#x00ed;a tambi&#x00e9;n lanzar otras excepciones no chequeadas
+                que no sean una <literal>HibernateException</literal>. Una vez m&#x00e1;s, no son recuperables y debe
+                tomarse una acci&#x00f3;n apropiada.
+            </para>
+
+            <para>
+                Hibernate envuelve <literal>SQLException</literal>s lanzadas mientras se interact&#x00fa;a con la base
+                de datos en una <literal>JDBCException</literal>. De hecho, Hibernate intentar&#x00e1; convertir la excepci&#x00f3;n
+                en una subclase de <literal>JDBCException</literal> m&#x00e1;s significativa. La <literal>SQLException</literal>
+                est&#x00e1; siempre disponible v&#x00ed;a <literal>JDBCException.getCause()</literal>. Hibernate convierte la 
+                <literal>SQLException</literal> en una subclase de <literal>JDBCException</literal> apropiada usando
+                el <literal>SQLExceptionConverter</literal> adjunto a la <literal>SessionFactory</literal>. Por defecto,
+                el <literal>SQLExceptionConverter</literal> est&#x00e1; definido para el dialecto configurado; sin embargo,
+                es tambi&#x00e9;n posible enchufar una implementaci&#x00f3;n personalizada (ver los javadocs de la clase
+                <literal>SQLExceptionConverterFactory</literal> para los detalles). Los subtipos est&#x00e1;ndar de
+                <literal>JDBCException</literal> son:
+            </para>
+
+            <itemizedlist spacing="compact">
+                <listitem>
+                    <para>
+                        <literal>JDBCConnectionException</literal> - indica un error con la comunicaci&#x00f3;n JDBC subyacente.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>SQLGrammarException</literal> - indica un problema de gram&#x00e1;tica o sint&#x00e1;xis con el
+                        SQL publicado.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>ConstraintViolationException</literal> - indica alguna forma de violaci&#x00f3;n de restricci&#x00f3;n
+                        de integridad.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>LockAcquisitionException</literal> - indica un error adquiriendo un nivel de bloqueo
+                        necesario para realizar una operaci&#x00f3;n solicitada.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <literal>GenericJDBCException</literal> - una excepci&#x00f3;n gen&#x00e9;rica que no cay&#x00f3; en ninguna de las
+                        otras categor&#x00ed;as.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="transactions-optimistic">
+        <title>Control optimista de concurrencia</title>
+
+        <para>
+            El &#x00fa;nico enfoque que es consistente con alta concurrencia y alta escalabilidad es el control
+            optimista de concurrencia con versionamiento. El chuequeo de versi&#x00f3;n usa n&#x00fa;meros de versi&#x00f3;n,
+            o timestamps, para detectar actualizaciones en conflicto (y para prevenir actualizaciones perdidas).
+            Hibernate provee para tres enfoques posibles de escribir c&#x00f3;digo de aplicaci&#x00f3;n que use concurrencia
+            optimista. Los casos de uso que hemos mostrado est&#x00e1;n en el contexto de transacciones de aplicaci&#x00f3;n
+            largas pero el chequeo de versiones tiene adem&#x00e1;s el beneficio de prevenir actualizaciones perdidas
+            en transacciones de base de datos solas.
+        </para>
+
+        <sect2 id="transactions-optimistic-manual">
+            <title>Chequeo de versiones de aplicaci&#x00f3;n</title>
+
+            <para>
+                En una implementaci&#x00f3;n sin mucha ayuda de Hibernate, cada interacci&#x00f3;n con la base de datos ocurre en una
+                nueva <literal>Session</literal> y el desarrollador es responsable de recargar todas las intancias
+                persistentes desde la base de datos antes de manipularlas. Este enfoque fuerza a la aplicaci&#x00f3;n a
+                realizar su propio chequeo de versiones para asegurar el aislamiento de transacciones de base de datos.
+                Es el enfoque m&#x00e1;s similar a los EJBs de entidad.
+            </para>
+
+            <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+int oldVersion = foo.getVersion();
+session.load( foo, foo.getKey() ); // load the current state
+if ( oldVersion != foo.getVersion() ) throw new StaleObjectStateException();
+foo.setProperty("bar");
+t.commit();
+session.close();]]></programlisting>
+
+            <para>
+                La propiedad <literal>version</literal> se mapea usando <literal>&lt;version&gt;</literal>,
+                e Hibernate la incrementar&#x00e1; autom&#x00e1;ticamente durante la limpieza si la entidad est&#x00e1; sucia.
+            </para>
+
+            <para>
+                Por supuesto, si est&#x00e1;s operando un entorno de baja-concurrencia-de-datos y no requieres
+                chequeo de versiones, puedes usar este enfoque y simplemente saltar el chequeo de versiones.
+                En ese caso, <emphasis>el &#x00fa;ltimo compromiso (commit) gana</emphasis> ser&#x00e1; la estrategia por
+                defecto para tus transacciones de aplicaci&#x00f3;n largas. Ten en mente que esto podr&#x00ed;a confundir
+                a los usuarios de la aplicaci&#x00f3;n, pues podr&#x00ed;an experimentar actualizaciones perdidas sin
+                mensajes de error ni chance de fusionar los cambios conflictivos.
+            </para>
+
+            <para>
+                Claramente, el chequeo manual de versiones es factible solamente en circunstancias muy triviales,
+                y no es pr&#x00e1;ctico para la mayor&#x00ed;a de aplicaciones. Frecuentemente, no s&#x00f3;lo intancias solas, sino grafos
+                completos de objetos modificados tienen que ser chequeados. Hibernate ofrece chequeo de versiones
+                autom&#x00e1;tico con el paradigma de dise&#x00f1;o de <literal>Session</literal> larga o de instancias separadas.
+            </para>
+
+        </sect2>
+
+        <sect2 id="transactions-optimistic-longsession">
+            <title>Sesi&#x00f3;n larga y versionado autom&#x00e1;tico</title>
+
+            <para>
+                Una sola instancia de <literal>Session</literal> y sus instancias persistentes
+                son usadas para toda la transacci&#x00f3;n de aplicaci&#x00f3;n. Hibernate chequea las versiones
+                de instancia en el momento de limpieza (flush), lanzando una excepci&#x00f3;n si se detecta
+                una modificaci&#x00f3;n concurrente. Concierne al desarrollador capturar y manejar esta excepci&#x00f3;n
+                (las opciones comunes son la oportunidad del usuario de fusionar los cambios, o recomenzar el
+                proceso de negocio sin datos a&#x00f1;ejos).
+            </para>
+
+            <para>
+                La <literal>Session</literal> se desconecta de cualquier conexi&#x00f3;n JDBC subyacente
+                al esperar por una interacci&#x00f3;n del usuario. Este enfoque es el m&#x00e1;s eficiente en t&#x00e9;rminos
+                de acceso a base de datos. La aplicaci&#x00f3;n no necesita tratar por s&#x00ed; misma con el chequeo de
+                versiones, ni re-uniendo instancias separadas, ni tiene que recargar instancias en cada
+                transacci&#x00f3;n de base de datos.
+            </para>
+
+            <programlisting><![CDATA[// foo is an instance loaded earlier by the Session
+session.reconnect(); // Obtain a new JDBC connection
+Transaction t = session.beginTransaction();
+foo.setProperty("bar");
+t.commit(); // End database transaction, flushing the change and checking the version
+session.disconnect(); // Return JDBC connection ]]></programlisting>
+
+            <para>
+                El objeto <literal>foo</literal> todav&#x00ed;a conoce en qu&#x00e9; <literal>Session</literal> fue cargado.
+                <literal>Session.reconnect()</literal> obtiene una nueva conexi&#x00f3;n (o puedes proveer una) y
+                reasume la sesi&#x00f3;n. El m&#x00e9;todo <literal>Session.disconnect()</literal> desconectar&#x00e1; la sesi&#x00f3;n
+                de la conexi&#x00f3;n JDBC y la devolver&#x00e1; la conexi&#x00f3;n al pool (a menos que hayas provisto la conexi&#x00f3;n).
+                Despu&#x00e9;s de la reconexi&#x00f3;n, para forzar un chequeo de versi&#x00f3;n en datos que no est&#x00e9;s actualizando,
+                puedes llamar a <literal>Session.lock()</literal> con <literal>LockMode.READ</literal> sobre
+                cualquier objeto que pudiese haber sido actualizado por otra transacci&#x00f3;n. No necesitas bloquear
+                ning&#x00fa;n dato que <emphasis>s&#x00ed; est&#x00e9;s</emphasis> actualizando.
+            </para>
+            
+            <para>
+                Si las llamadas expl&#x00ed;citas a <literal>disconnect()</literal> y <literal>reconnect()</literal>
+                son muy onerosas, puedes usar en cambio <literal>hibernate.connection.release_mode</literal>.
+            </para>
+
+            <para>
+                Este patr&#x00f3;n es problem&#x00e1;tico si la <literal>Session</literal> es demasiado grande para ser almacenada
+                durante el tiempo de pensar del usuario, por ejemplo, una <literal>HttpSession</literal> debe
+                mantenerse tan peque&#x00f1;a como sea posible. Ya que la <literal>Session</literal> es tambi&#x00e9;n el cach&#x00e9;
+                (obligatorio) de primer nivel y contiene todos los objetos cargados, podemos probablemente cargar
+                esta estrategia s&#x00f3;lo para unos pocos ciclos petici&#x00f3;n/respuesta. Esto est&#x00e1; de hecho recomendado, ya que
+                la <literal>Session</literal> tendr&#x00e1; pronto tambi&#x00e9;n datos a&#x00f1;ejos.
+            </para>
+
+            <para>
+                Nota tambi&#x00e9;n que debes mantener la <literal>Session</literal> desconectada pr&#x00f3;xima a la capa
+                de persistencia. En otras palabras, usa una sesi&#x00f3;n de EJB con estado para tener la
+                <literal>Session</literal> y no transferirla a la capa web para almacenarla en la
+                <literal>HttpSession</literal> (ni incluso serializarla a una capa separada).
+            </para>
+
+        </sect2>
+
+        <sect2 id="transactions-optimistic-detached">
+            <title>Objetos separados y versionado autom&#x00e1;tico</title>
+
+            <para>
+                Cada interacci&#x00f3;n con el almac&#x00e9;n persistente ocurre en una nueva <literal>Session</literal>.
+                Sin embargo, las mismas instancias persistentes son reusadas para cada interacci&#x00f3;n con la base de
+                datos. La aplicaci&#x00f3;n manipula el estado de las instancias separadas originalmente cargadas en otra
+                <literal>Session</literal> y luego las readjunta usando <literal>Session.update()</literal>,
+                <literal>Session.saveOrUpdate()</literal>, o <literal>Session.merge()</literal>.
+            </para>
+
+            <programlisting><![CDATA[// foo is an instance loaded by a previous Session
+foo.setProperty("bar");
+session = factory.openSession();
+Transaction t = session.beginTransaction();
+session.saveOrUpdate(foo); // Use merge() if "foo" might have been loaded already
+t.commit();
+session.close();]]></programlisting>
+
+            <para>
+                De nuevo, Hibernate chequear&#x00e1; las versiones de instancia durante la limpieza (flush),
+                lanzando una excepci&#x00f3;n si ocurrieron actualizaciones en conflicto.
+            </para>
+
+            <para>
+                Puedes tambi&#x00e9;n llamar a <literal>lock()</literal> en vez de <literal>update()</literal>
+                y usar <literal>LockMode.READ</literal> (realizando un chequeo de versi&#x00f3;n, puenteando
+                todos los cach&#x00e9;s) si est&#x00e1;s seguro que el objeto no ha sido modificado.
+            </para>
+
+        </sect2>
+
+        <sect2 id="transactions-optimistic-customizing">
+            <title>Personalizando el versionado autom&#x00e1;tico</title>
+
+            <para>
+                Puedes deshabilitar el incremento de versi&#x00f3;n autom&#x00e1;tico de Hibernate para propiedades en particular
+                y colecciones estableciendo el atributo de mapeo <literal>optimistic-lock</literal> a 
+                <literal>false</literal>. Hibernate entonces no incrementar&#x00e1; ya m&#x00e1;s las versiones si la propiedad est&#x00e1;
+                sucia.
+            </para>
+
+            <para>
+                Los esquemas de base de datos heredados son frecuentemente est&#x00e1;ticos y no pueden ser modificados.
+                U otras aplicaciones podr&#x00ed;an tambi&#x00e9;n acceder la misma base de datos y no saber c&#x00f3;mo manejar los n&#x00fa;meros
+                de versi&#x00f3;n ni incluso timestamps. En ambos casos, el versionado no puede confiarse a una columna en
+                particular en una tabla. Para forzar un chequeo de versiones sin un mapeo de propiedad de versi&#x00f3;n o
+                timestamp, con una comparaci&#x00f3;n del estado de todos los campos en una fila, activa
+                <literal>optimistic-lock="all"</literal> en el mapeo de <literal>&lt;class&gt;</literal>.
+                Nota que esto conceptualmente funciona solamente si Hibernate puede comparar el estado viejo y nuevo,
+                es decir, si usas una sola <literal>Session</literal> larga y no
+                sesi&#x00f3;n-por-petici&#x00f3;n-con-instancias-separadas.
+            </para>
+
+            <para>
+                A veces las modificaciones concurrentes pueden permitirse, en cuanto los cambios que hayan sido
+                hechos no se traslapen. Si estableces <literal>optimistic-lock="dirty"</literal> al mapear la
+                <literal>&lt;class&gt;</literal>, Hibernate s&#x00f3;lo comparar&#x00e1; los campos sucios durante la limpieza.
+            </para>
+
+            <para>
+                En ambos casos, con columnas de versi&#x00f3;n/timestamp dedicadas o con comparaci&#x00f3;n de campos
+                completa/sucios, Hibernate usa una sola sentencia <literal>UPDATE</literal>
+                (con una cl&#x00e1;usula <literal>WHERE</literal> apropiada) por entidad para ejecutar el chequeo
+                de versiones y actualizar la informaci&#x00f3;n. Si usas persistencia transitiva para la re-uni&#x00f3;n
+                en cascada de entidades asociadas, Hibernate podr&#x00ed;a ejecutar actualizaciones innecesarias.
+                Esto usualmente no es un problema, pero podr&#x00ed;an ejecutarse disparadores (triggers) 
+                <emphasis>on update</emphasis> en la base de datos incluso cuando no se haya hecho ning&#x00fa;n cambio
+                a las instancias separadas. Puedes personalizar este comportamiento estableciendo
+                <literal>select-before-update="true"</literal> en el mapeo de <literal>&lt;class&gt;</literal>,
+                forzando a Hibernate a <literal>SELECT</literal> la instancia para asegurar que las actualizaciones
+                realmente ocurran, antes de actualizar la fila.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="transactions-locking">
+        <title>Bloqueo pesimista</title>
+
+        <para>
+            No se pretende que los usuarios gasten mucho tiempo preocup&#x00e1;ndose de las estrategias de bloqueo.
+            Usualmente es suficiente con especificar un nivel de aislamiento para las conexiones JDBC y entonces
+            simplemente dejar que la base de datos haga todo el trabajo. Sin embargo, los usuarios avanzados pueden
+            a veces obtener bloqueos exclusivos pesimistas, o reobtener bloqueos al comienzo de una nueva
+            transacci&#x00f3;n.
+        </para>
+
+        <para>
+            &#x00a1;Hibernate siempre usar&#x00e1; el mecanismo de bloqueo de la base de datos, nunca bloqueo
+            de objetos en memoria!
+        </para>
+
+        <para>
+            La clase <literal>LockMode</literal> define los diferentes niveles de bloqueo que pueden ser adquiridos
+            por Hibernate. Un bloqueo se obtiene por los siguientes mecanismos:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    <literal>LockMode.WRITE</literal> se adquiere autom&#x00e1;ticamente cuando Hibernate actualiza o
+                    inserta una fila.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>LockMode.UPGRADE</literal> puede ser adquirido bajo petici&#x00f3;n expl&#x00ed;cita del usuario
+                    usando <literal>SELECT ... FOR UPDATE</literal> en base de datos que soporten esa sint&#x00e1;xis.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>LockMode.UPGRADE_NOWAIT</literal> puede ser adquirido bajo petici&#x00f3;n expl&#x00ed;cita del usuario
+                    usando un <literal>SELECT ... FOR UPDATE NOWAIT</literal> bajo Oracle.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    <literal>LockMode.READ</literal> es adquirido autom&#x00e1;ticamente cuando Hibernate lee datos
+                    bajo los niveles de aislamiento Repeatable Read o Serializable. Puede ser readquirido por
+                    pedido expl&#x00ed;cito del usuario.
+                </para>
+            </listitem>
+        <listitem>
+        <para>
+            <literal>LockMode.NONE</literal> representa la ausencia de un bloqueo. Todos los objetos se pasan
+            a este modo de bloqueo al final de una <literal>Transaction</literal>. Los objetos asociados con una
+            sesi&#x00f3;n v&#x00ed;a una llamada a <literal>update()</literal> o <literal>saveOrUpdate()</literal> tambi&#x00e9;n
+            comienzan en este modo de bloqueo.
+        </para>
+        </listitem>
+        </itemizedlist>
+
+        <para>
+            La "petici&#x00f3;n expl&#x00ed;cita del usuario" se expresa en una de las siguientes formas:
+        </para>
+
+        <itemizedlist spacing="compact">
+            <listitem>
+                <para>
+                    Una llamada a <literal>Session.load()</literal>, especificando un <literal>LockMode</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Una llamada a <literal>Session.lock()</literal>.
+                </para>
+            </listitem>
+            <listitem>
+                <para>
+                    Una llamada a <literal>Query.setLockMode()</literal>.
+                </para>
+            </listitem>
+        </itemizedlist>
+
+        <para>
+            Si se llama a <literal>Session.load()</literal> con <literal>UPGRADE</literal> o
+            <literal>UPGRADE_NOWAIT</literal>, y el objeto pedido no ha sido a&#x00fa;n cargado por la sesi&#x00f3;n, el objeto es
+            cargado usando <literal>SELECT ... FOR UPDATE</literal>. Si se llama a <literal>load()</literal> para
+            un objeto que ya est&#x00e9; cargado con un bloqueo menos restrictivo que el pedido, Hibernate llama a
+            <literal>lock()</literal> para ese objeto.
+        </para>
+
+        <para>
+            <literal>Session.lock()</literal> realiza un chequeo de n&#x00fa;mero de versi&#x00f3;n si el modo de bloqueo especificado
+            es <literal>READ</literal>, <literal>UPGRADE</literal> o <literal>UPGRADE_NOWAIT</literal>. (En el caso de
+            <literal>UPGRADE</literal> o <literal>UPGRADE_NOWAIT</literal>, se usa
+            <literal>SELECT ... FOR UPDATE</literal>.)
+        </para>
+
+        <para>
+            Si la base de datos no soporta el modo de bloqueo solicitado, Hibernate usar&#x00e1; un modo alternativo
+            apropiado (en vez de lanzar una excepci&#x00f3;n). Esto asegura que las aplicaciones ser&#x00e1;n portables.
+        </para>
+
+    </sect1>
+
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/tutorial.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/tutorial.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/tutorial.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/tutorial.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,1270 @@
+<chapter id="tutorial">
+    <title>Introducci&#x00f3;n a Hibernate</title>
+    
+    <sect1 id="tutorial-intro">
+        <title>Prefacio</title>
+        
+        <para>
+            Este cap&#x00ed;tulo es un tutorial introductorio de Hibernate. Comenzamos con
+            una aplicaci&#x00f3;n simple de l&#x00ed;nea de comandos usando un base de datos
+            en-memoria y desarroll&#x00e1;ndola en f&#x00e1;cil para entender los pasos.
+        </para>
+
+        <para>
+            Este tutorial est&#x00e1; concebido para usuarios nuevos de Hibernate pero
+            requiere conocimiento en Java y SQL. Est&#x00e1; basado en un tutorial de
+            Michael Gloegl. Las bibliotecas de terceros que mencionamos son para JDK 1.4
+            y 5.0. Podr&#x00ed;as necesitar otras para JDK 1.3.
+        </para>
+
+    </sect1>
+    
+    <sect1 id="tutorial-firstapp">
+        <title>Parte 1 - La primera Aplicaci&#x00f3;n Hibernate</title>
+
+        <para>
+            Primero, crearemos una aplicaci&#x00f3;n simple de Hibenate basada en consola.
+            Usamos usamos una base de datos en-memoria (HSQL DB), de modo que no necesitamos
+            instalar ning&#x00fa;n servidor de base de datos.
+        </para>
+
+        <para>
+            Asumamos que necesitamos una aplicaci&#x00f3;n peque&#x00f1;a de base de datos que
+            pueda almacenar eventos que queremos atender, e informaci&#x00f3;n acerca de los
+            hostales de estos eventos.
+        </para>
+            
+        <para>
+            La primera cosa que hacemos, es armar nuestro directorio de desarrollo y poner
+            en &#x00e9;l todas las bibliotecas Java que necesitamos. Descarga la distribuci&#x00f3;n
+            de Hibernate del sitio web de Hibernate. Extrae el paquete y coloca todas las
+            bibliotecas requeridas encontradas en <literal>/lib</literal> dentro del directorio
+            <literal>/lib</literal> de nuestro nuevo directorio de desarrollo de trabajo.
+            Debe asemejarse a esto:
+        </para>
+            
+        <programlisting><![CDATA[.
++lib
+  antlr.jar
+  cglib-full.jar
+  asm.jar
+  asm-attrs.jars
+  commons-collections.jar
+  commons-logging.jar
+  ehcache.jar
+  hibernate3.jar
+  jta.jar
+  dom4j.jar
+  log4j.jar ]]></programlisting>
+
+        <para>
+            Este es el conjunto m&#x00ed;nimo de bibliotecas requeridas para Hibernate (observa que
+            tambi&#x00e9;n hemos copiado hibernate3.jar, el fichero principal). Ver el fichero
+            <literal>README.txt</literal> en el directorio <literal>lib/</literal> de la distribuci&#x00f3;n
+            de Hibernate para m&#x00e1;s informaci&#x00f3;n sobre bibliotecas de terceros requeridas y
+            opcionales. (Realmente, Log4J no es requerida aunque preferida por muchos desarrolladores).
+        </para>
+
+        <para>
+            Por siguiente, creamos una clase que represente el evento que queremos
+            almacenar en base de datos.
+        </para>
+      
+        <sect2 id="tutorial-firstapp-firstclass">
+            <title>La primera clase</title>
+            
+            <para>
+                Nuestra primera clase persistente es un JavaBean simple con algunas propiedades:
+            </para>
+
+            <programlisting><![CDATA[import java.util.Date;
+
+public class Event {
+    private Long id;
+
+    private String title;
+    private Date date;
+
+    Event() {}
+
+    public Long getId() {
+        return id;
+    }
+
+    private void setId(Long id) {
+        this.id = id;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+}]]></programlisting>
+
+            <para>
+                Puedes ver que esta clase usa las convenciones de nombrado est&#x00e1;ndar de JavaBean
+                para m&#x00e9;todos getter y setter de propiedad, as&#x00ed; como visibilidad privada
+                para los campos. Esto es un dise&#x00f1;o recomendado, aunque no requerido. Hibernate
+                tambi&#x00e9;n puede acceder a los campos directamente; el beneficio de los m&#x00e9;todos
+                de acceso es la robustez para la refactorizaci&#x00f3;n.
+            </para>
+
+            <para>
+                La propiedad <literal>id</literal> tiene un valor &#x00fa;nico de identificador para
+                un evento en particular. Todas las clase de entidad persistentes ( tambi&#x00e9;n hay
+                clases dependientes menos importantes) necesitar&#x00e1;n una propiedad identificadora
+                similar si queremos usar el conjunto completo de funcionalidades de Hibernate. De hecho,
+                la mayor&#x00ed;a de las aplicaciones (esp. aplicaciones web) necesitan distinguir
+                objetos por identificador, de modo que debes considerar esto como un aspecto en vez de una
+                limitaci&#x00f3;n. Sin embargo, usualmente no manipulamos la identidad de un objeto, por
+                lo tanto el m&#x00e9;todo setter debe ser privado. S&#x00f3;lo Hibernate asignar&#x00e1;
+                identificadores cuando un objeto sea salvado. Puedes ver que Hibernate puede acceder a
+                m&#x00e9;todos de acceso p&#x00fa;blicos, privados y protegidos, tanto como directamente a
+                campos (p&#x00fa;blicos, privados y protegidos). La elecci&#x00f3;n est&#x00e1; en ti,
+                y puedes ajustarla a tu dise&#x00f1;o de aplicaci&#x00f3;n.
+            </para>
+
+            <para>
+                El constructor sin argumentos es un requerimiento para todas las clases persistentes.
+                Hibernate tiene que crear objetos para ti, usando reflecci&#x00f3;n Java. El constructor
+                puede ser privado, sin embargo, la visibilidad de paquete es requerida para la generaci&#x00f3;n
+                de proxies en tiempo de ejecuci&#x00f3;n y la recuperaci&#x00f3;n de datos sin
+                instrumentaci&#x00f3;n del bytecode.
+            </para>
+
+            <para>
+                Coloca este fichero de c&#x00f3;digo Java en un directorio llamado <literal>src</literal>
+                en la carpeta de desarrollo. El directorio ahora debe verse como esto:
+            </para>
+
+            <programlisting><![CDATA[.
++lib
+  <Hibernate and third-party libraries>
++src
+  Event.java]]></programlisting>
+
+            <para>
+                En el pr&#x00f3;ximo paso, le decimos a Hibernate sobre esta clase persistente.
+            </para>
+                
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-mapping">
+            <title>El fichero de mapeo</title>
+
+            <para>
+                Hibernate necesita saber c&#x00f3;mo cargar y almacenar objetos de la
+                clase persistente. Aqu&#x00ed; es donde el fichero de mapeo de Hibernate
+                entra en juego. El fichero de mapeo le dice a Hibernate a qu&#x00e9; tabla en
+                la base de datos tiene que acceder, y qu&#x00e9; columnas en esta tabla debe usar.
+            </para>
+
+            <para>
+                La estructura b&#x00e1;sica de un fichero de mapeo se parece a esto:
+            </para>
+
+            <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+[...]
+</hibernate-mapping>]]></programlisting>
+
+            <para>
+                Observa que el DTD de Hibernate es muy sofisticado. Puedes usarlo para
+                autocompleci&#x00f3;n de los elementos y atributos XML de mapeo en tu
+                editor o IDE. Debes tambi&#x00e9;n abrir el fichero DTD en tu editor de
+                texto. Es la forma m&#x00e1;s f&#x00e1;cil para tener un panorama de todos
+                los elementos y atributos y ver los valores por defectos, as&#x00ed; como
+                algunos comentarios. Nota que Hibernate no cargar&#x00e1; el fichero DTD de
+                la web, sino que primero buscar&#x00e1; en el classpath de la aplicaci&#x00f3;n.
+                El fichero DTD est&#x00e1; inclu&#x00ed;do en <literal>hibernate3.jar</literal>
+                as&#x00ed; como tambi&#x00e9;n en el directorio <literal>src/</literal> de la
+                distribuci&#x00f3;n de Hibernate.
+            </para>
+
+            <para>
+                Omitiremos la declaraci&#x00f3;n de DTD en futuros ejemplos para acortar
+                el c&#x00f3;digo. Por supuesto, no es opcional.
+            </para>
+
+            <para>
+                Entre las dos etiquetas <literal>hibernate-mapping</literal>, incluye
+                un elemento <literal>class</literal>. Todas las clases de entidad
+                persistentes (de nuevo, podr&#x00ed;a haber m&#x00e1;s adelante clases
+                dependientes, que no sean entidades de-primera-clase) necesitan dicho mapeo
+                a una tabla en la base de datos SQL:
+            </para>
+
+            <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="Event" table="EVENTS">
+
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+            <para>
+                Hasta ahora dijimos a Hibernate c&#x00f3;mo persistir y cargar el objeto
+                de clase <literal>Event</literal> a la tabla <literal>EVENTS</literal>,
+                cada instancia representada por una fila en esta tabla. Ahora continuamos con
+                un mapeo de la propiedad de identificado &#x00fa;nico a la clave primaria
+                de la tabla. Adem&#x00e1;s, como no queremos cuidar del manejo de este identificador,
+                configuramos la estrategia de generaci&#x00f3;n de identificadores para una columna
+                clave primaria delegada:
+            </para>
+
+            <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="Event" table="EVENTS">
+        <id name="id" column="EVENT_ID">
+            <generator class="increment"/>
+        </id>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+            <para>
+                El elemento <literal>id</literal> el la declaraci&#x00f3;n de la propiedad
+                identificadora, <literal>name="id"</literal> declara el nombre de la
+                propiedad Java. Hibernate usar&#x00e1; los m&#x00e9;todos getter y setter
+                para acceder a la propiedad. El attributo de columna dice a Hibernate cu&#x00e1;l
+                columna de la tabla <literal>EVENTS</literal> usamos para esta clave primaria.
+                El elemento anidado <literal>generator</literal> especifica la estrategia de
+                generaci&#x00f3;n de identificadores, en este caso usamos <literal>increment</literal>,
+                que es un m&#x00e9;todo muy simple de incremento de n&#x00fa;mero en-memoria
+                &#x00fa;til mayormente para testeo (y tutoriales). Hibernate tambi&#x0e9;n
+                soporta identificadores generados por base de datos, globalmente &#x00fa;nicos,
+                as&#x00ed; como tambi&#x00e9;n asignados por aplicaci&#x00f3;n (o cualquier
+                estrategia para la que hayas escrito una extensi&#x00f3;n).
+            </para>
+
+            <para>
+                Finalmente inclu&#x00ed;mos declaraciones para las propiedades persistentes
+                de la clases en el fichero de mapeo. Por defecto, ninguna propiedad de la clase
+                se considera persistente:
+            </para>
+            
+            <programlisting><![CDATA[
+<hibernate-mapping>
+
+    <class name="Event" table="EVENTS">
+        <id name="id" column="EVENT_ID">
+            <generator class="increment"/>
+        </id>
+        <property name="date" type="timestamp" column="EVENT_DATE"/>
+        <property name="title"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+            
+            <para>
+                Al igual que con el elemento <literal>id</literal>, el atributo <literal>name</literal>
+                del elemento <literal>property</literal> dice a Hibernate c&#x00e1;les m&#x00e9;todos
+                getter y setter usar.
+            </para>
+
+            <para>
+                ¿Por qu&#x00e9; el mapeo de la propiedad <literal>date</literal>
+                incluye el atributo <literal>column</literal>, pero el de la de
+                <literal>title</literal> no? Sin el atributo <literal>column</literal>
+                Hibernate usa por defecto el nombre de propiedad como nombre de columna.
+                Esto funciona bien para <literal>title</literal>. Sin embargo,
+                However, <literal>date</literal> es una palabra reservada en la
+                mayor&#x00ed;a de las bases de datos, as&#x00ed; que mejor la mapeamos
+                a un nombre diferente.
+            </para>
+
+            <para>
+                La pr&#x00f3;xima cosa interesante es que el mapeo de <literal>title</literal> 
+                carece de un atributo <literal>type</literal>. Los tipos que declaramos y usamos
+                en el fichero de mapeo no son, como podr&#x00ed;as esperar, tipos de datos Java.
+                Tampoco son tipos de base de datos SQL. Estos tipos son los llamados as&#x00ed;
+                <emphasis>Tipos de mapeo de Hibernate</emphasis>, convertidores que pueden
+                traducir de tipos Java a SQL y vice versa. De nuevo, Hibernate intentar&#x00e1;
+                determinar la conversi&#x00f3;n y el mapeo mismo de tipo correctos si el atributo
+                <literal>type</literal> no estuviese presente en el mapeo. En algunos casos esta
+                detecci&#x00f3;n autom&#x00e1;tica (usando reflecci&#x00f3;n en la clase Java)
+                puede no tener lo que esperas o necesitas. Este es el caso de la propiedad
+                <literal>date</literal>. Hibernate no puede saber is la propiedad mapear&#x00e1;
+                a una columna <literal>date</literal>, <literal>timestamp</literal> o
+                <literal>time</literal>. Declaramos que queremos preservar la informaci&#x00f3;n
+                completa de fecha y hora mapeando la propiedad con un <literal>timestamp</literal>.
+            </para>
+
+            <para>
+                Este fichero de mapeo debe ser salvado como <literal>Event.hbm.xml</literal>,
+                justo en el directorio pr&#x00f3;ximo al fichero de c&#x00f3;digo fuente de
+                la clase Java <literal>Event</literal>. El nombrado de los ficheros de mapeo
+                puede ser arbitrario, sin embargo, el sufijo <literal>hbm.xml</literal> se ha
+                vuelto una convenci&#x00f3;n el la comunidad de desarrolladores de Hibernate.
+                La estructura de directorio debe ahora verse como esto:
+            </para>
+
+            <programlisting><![CDATA[.
++lib
+  <Hibernate and third-party libraries>
++src
+  Event.java
+  Event.hbm.xml]]></programlisting>
+
+             <para>
+                 Continuamos con la configuraci&#x00f3;n principal de Hibernate.
+             </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-configuration">
+            <title>Configuraci&#x00f3;n de Hibernate</title>
+
+            <para>
+                Tenemos ahora una clase persistente y su fichero de mapeo en su sitio. Es momento de
+                configurar Hibernate. Antes que hagamos esto, necesitaremos una base de datos.
+                HSQL DB, un DBMS SQL en-memoria basado en Java, puede ser descargado del sitio web
+                de HSQL DB. Realmente, de esta descarga s&#x00f3;lo necesitas el <literal>hsqldb.jar</literal>.
+                Coloca este fichero en el directorio <literal>lib/</literal> de la carpeta de desarrollo.
+            </para>
+
+            <para>
+                Crea un directorio llamado <literal>data</literal> en la ra&#x00ed;z del directorio de
+                desarrollo. All&#x00ed; es donde HSQL DB almacenar&#x00e1; sus ficheros de datos.
+            </para>
+
+            <para>
+                Hibernate es la capa en tu aplicaci&#x00f3;n que se conecta a esta base de datos,
+                de modo que necesita informaci&#x00f3;n de conexi&#x00f3;n. Las conexiones se hacen
+                a trav&#x00e9;s de un pool de conexiones JDBC, que tamb&#x00e9;n tenemos que configurar.
+                La distribuci&#x00f3;n de Hibernate contiene muchas herramientas de pooling de conexiones
+                JDBC de c&#x00f3;digo abierto, pero para este tutorial usaremos el pool de conexiones
+                prefabricado dentro de Hibernate. Observa que tienes que copiar la biblioteca requerida
+                en tu classpath y usar diferentes configuraciones de pooling de conexiones si quieres
+                usar un software de pooling JDBC de terceros de calidad de producci&#x00f3;n.
+            </para>
+
+            <para>
+                Para la configuraci&#x00f3;n de Hibernate, podemos usar un fichero
+                <literal>hibernate.properties</literal> simple, un fichero <literal>hibernate.cfg.xml</literal>
+                ligeramente m&#x00e1;s sofisticado, o incluso una configuraci&#x00f3;n completamente
+                program&#x00e1;tica. La mayor&#x00ed;a de los usuarios prefieren el fichero de
+                configuraci&#x00f3;n XML:
+            </para>
+
+            <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+    <session-factory>
+
+        <!-- Database connection settings -->
+        <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
+        <property name="connection.url">jdbc:hsqldb:data/tutorial</property>
+        <property name="connection.username">sa</property>
+        <property name="connection.password"></property>
+
+        <!-- JDBC connection pool (use the built-in) -->
+        <property name="connection.pool_size">1</property>
+
+        <!-- SQL dialect -->
+        <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
+
+        <!-- Echo all executed SQL to stdout -->
+        <property name="show_sql">true</property>
+
+        <!-- Drop and re-create the database schema on startup -->
+        <property name="hbm2ddl.auto">create</property>
+
+        <mapping resource="Event.hbm.xml"/>
+
+    </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+            <para>
+                Observa que esta configuraci&#x00f3;n XML usa un DTD diferente.
+                Configuramos la <literal>SessionFactory</literal> de Hibernate, una
+                f&#x00e1;brica global responsable de una base de datos en particular.
+                Si tienes varias bases de datos, usa varias configuraciones
+                <literal>&lt;session-factory&gt;</literal> , usualmente en varios
+                ficheros de configuraci&#x00f3;n (para un arranque m&#x00e1;s f&#x00e1;cil).
+            </para>
+
+            <para>
+                Los primeros cuatro elementos <literal>property</literal> contienen la configuraci&#x00f3;n
+                necesaria para la conexi&#x00f3;n JDBC. El elemento de dialecto <literal>property</literal>
+                especifica la variante de SQL en particular que genera Hibernate. La opci&#x00f3;n
+                <literal>hbm2ddl.auto</literal> activa la generaci&#x00f3;n autom&#x00e1;tica de esquemas
+                de base de datos, directamente en la base de datos. Esto, por supuesto, puede desactivarse
+                (quitando la opci&#x00f3;n config) o redirigido a un fichero con la ayuda de la tarea
+                de Ant <literal>SchemaExport</literal>. Finalmente, agregamos el(los) fichero(s) de mapeo
+                para clases persistentes.
+            </para>
+
+            <para>
+                Copia este fichero dentro del directorio de c&#x00f3;digo fuente, de modo que
+                termine ubicado en la rai&#x00ed;z del classpath. Hibernate busca autom&#x00e1;ticamente
+                un fichero llamado <literal>hibernate.cfg.xml</literal> en la ra&#x00ed;z del classpath
+                al arrancar.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-ant">
+            <title>Construyendo con Ant</title>
+
+            <para>
+                Construiremos ahora el tutorial con Ant. Necesitar&#x00e1;s tener Ant instalado.
+                Obt&#x00e9;nlo de <ulink url="http://ant.apache.org/bindownload.cgi">P&#x00e1;gina
+                de descarga de Ant</ulink>. No se cubrir&#x00e1; aqu&#x00ed; c&#x00f3;mo instalar Ant.
+                Por favor refi&#x00e9;rete al <ulink url="http://ant.apache.org/manual/index.html">
+                Manual de Ant</ulink>. Despu&#x00e9;s que hayas instalado Ant, podemos comenzar a
+                crear el buildfile. Ser&#x00e1; llamado <literal>build.xml</literal> y colocado
+                directamente en el directorio de desarrollo.
+            </para>
+
+            <note>
+                <title>Reparar Ant</title>
+                <para>
+                    Observa que la distribuci&#x00f3;n de Ant est&#x00e1; por defecto rota
+                    (como se describe en el FAQ de Ant) y tiene que ser reparado por ti,
+                    por ejemplo, si quisieras usar JUnit desde dentro de tu fichero de construcci&#x00f3;n.
+                    Para hacer que funcione la tarea de JUnit (no lo necesitaremos en este tutorial),
+                    copia junit.jar a <literal>ANT_HOME/lib</literal> o quita el trozo de plugin
+                    <literal>ANT_HOME/lib/ant-junit.jar</literal>.
+                </para>
+            </note>
+
+            <para>
+                Un fichero de construcci&#x00f3;n b&#x00e1;sico se ve como esto:
+            </para>
+
+            <programlisting><![CDATA[<project name="hibernate-tutorial" default="compile">
+
+    <property name="sourcedir" value="${basedir}/src"/>
+    <property name="targetdir" value="${basedir}/bin"/>
+    <property name="librarydir" value="${basedir}/lib"/>
+
+    <path id="libraries">
+        <fileset dir="${librarydir}">
+            <include name="*.jar"/>
+        </fileset>
+    </path>
+
+    <target name="clean">
+        <delete dir="${targetdir}"/>
+        <mkdir dir="${targetdir}"/>
+    </target>
+
+    <target name="compile" depends="clean, copy-resources">
+      <javac srcdir="${sourcedir}"
+             destdir="${targetdir}"
+             classpathref="libraries"/>
+    </target>
+
+    <target name="copy-resources">
+        <copy todir="${targetdir}">
+            <fileset dir="${sourcedir}">
+                <exclude name="**/*.java"/>
+            </fileset>
+        </copy>
+    </target>
+
+</project>]]></programlisting>
+
+            <para>
+                Esto dir&#x00e1; a Ant que agregue todos los ficheros en el directorio lib que terminen con
+                <literal>.jar</literal> al classpath usado para la compilaci&#x00f3;n. Tambi&#x00e9;n copiar&#x00e1;
+                todos los ficheros que no sean c&#x00f3;digo Java al directorio objetivo, por ejemplo,
+                ficheros de configuraci&#x00f3;n y mapeos de Hibernate. Si ahora corres Ant, debes obtener
+                esta salida:
+            </para>
+
+            <programlisting><![CDATA[C:\hibernateTutorial\>ant
+Buildfile: build.xml
+
+copy-resources:
+     [copy] Copying 2 files to C:\hibernateTutorial\bin
+
+compile:
+    [javac] Compiling 1 source file to C:\hibernateTutorial\bin
+
+BUILD SUCCESSFUL
+Total time: 1 second ]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-helpers">
+            <title>Arranque y ayudantes</title>
+
+            <para>
+                Es momento de cargar y almacenar algunos objetos <literal>Event</literal>,
+                pero primero tenemos que completar la configuraci&#x00f3;n de alg&#x00fa;n
+                c&#x00f3;digo de infraestructura. Tenemos que arrancar Hibernate. Este
+                arranque incluye construir un objeto <literal>SessionFactory</literal> global
+                y almacenarlo en alg&#x00fa;n sitio de f&#x00e1;cil acceso en el c&#x00f3;digo
+                de aplicaci&#x00f3;n. Una <literal>SessionFactory</literal> puede abrir nuevas
+                <literal>Session</literal>'s. Una <literal>Session</literal> representa un unidad
+                de trabajo mono-hebra. La <literal>SessionFactory</literal> es un objeto global
+                seguro entre hebras, instanciado una sola vez.
+            </para>
+
+            <para>
+                Crearemos una clase de ayuda <literal>HibernateUtil</literal> que cuide del
+                arranque y haga conveniente el manejo de <literal>Session</literal>.
+                El as&#x00ed; llamado patr&#x00f3;n <emphasis>Sesi&#x00f3;n de Hebra Local
+                (ThreadLocal Session)</emphasis> es &#x00fa;til aqu&#x00ed;; mantenemos la unidad
+                de trabajo actual asociada a la hebra actual. Echemos una mirada a la implementaci&#x00f3;n:
+            </para>
+
+            <programlisting><![CDATA[import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+    public static final SessionFactory sessionFactory;
+
+    static {
+        try {
+            // Create the SessionFactory from hibernate.cfg.xml
+            sessionFactory = new Configuration().configure().buildSessionFactory();
+        } catch (Throwable ex) {
+            // Make sure you log the exception, as it might be swallowed
+            System.err.println("Initial SessionFactory creation failed." + ex);
+            throw new ExceptionInInitializerError(ex);
+        }
+    }
+
+    public static final ThreadLocal session = new ThreadLocal();
+
+    public static Session currentSession() throws HibernateException {
+        Session s = (Session) session.get();
+        // Open a new Session, if this thread has none yet
+        if (s == null) {
+            s = sessionFactory.openSession();
+            // Store it in the ThreadLocal variable
+            session.set(s);
+        }
+        return s;
+    }
+
+    public static void closeSession() throws HibernateException {
+        Session s = (Session) session.get();
+        if (s != null)
+            s.close();
+        session.set(null);
+    }
+}]]></programlisting>
+
+            <para>
+                Esta clase no &#x00f3;lo produce la <literal>SessionFactory</literal> global en
+                su inicializador static (llamado s&#x00f3;lo una vez por la JVM al cargar la clase),
+                sino que tambi&#x00e9;n tiene una variable <literal>ThreadLocal</literal> para
+                tener la <literal>Session</literal> para la hebra actual. No importa cu&#x00e1;ndo
+                llames a <literal>HibernateUtil.currentSession()</literal>, siempre devolver&#x00e1;
+                la misma unidad de trabajo de Hibernate en la misma hebra. Una llamada a
+                <literal>HibernateUtil.closeSession()</literal> termina la unidad de trabajo actualmente
+                asociada a la hebra.
+            </para>
+
+            <para>
+                Aseg&#x00fa;rate de entender el concepto Java de una variable local a una hebra antes
+                de usar esta ayuda. Una clase <literal>HibernateUtil</literal> m&#x00e1;s potente puede
+                encontrarse en <literal>CaveatEmptor</literal>, http://caveatemptor.hibernate.org/, 
+                as&#x00ed; como en el libro "Java Persistence with Hibernate". Observa que esta clase no es necesaria
+                si despliegas Hibernate en un servidor de aplicaciones J2EE: una <literal>Session</literal>
+                ser&#x00e1; autom&#x00e1;ticamente ligada a la transacci&#x00f3;n JTA actual, y puedes
+                buscar la <literal>SessionFactory</literal> a trav&#x00e9;s de JNDI. Si usas JBoss AS,
+                Hibernate puede ser desplegado como un servicio de sistema manejado y autom&#x00e1;ticamente
+                ligar&#x00e1; la <literal>SessionFactory</literal> a un nombre JNDI.
+            </para>
+
+            <para>
+                Coloca <literal>HibernateUtil.java</literal> en el directorio de fuentes de desarrollo,
+                junto a <literal>Event.java</literal>:
+            </para>
+
+            <programlisting><![CDATA[.
++lib
+  <Hibernate and third-party libraries>
++src
+  Event.java
+  Event.hbm.xml
+  HibernateUtil.java
+  hibernate.cfg.xml
++data
+build.xml]]></programlisting>
+
+            <para>
+                Esto tambi&#x00e9;n debe compilar sin problemas. Finalmente necesitamos configurar
+                un sistema de logging (registro). Hibernate usa commons logging y te deja la elecci&#x00f3;n
+                entre Log4J y logging de JDK 1.4. La mayor&#x00ed;a de los desarrolladores prefieren
+                Log4J: copia <literal>log4j.properties</literal> de la distribuci&#x00f3;n de Hibernate
+                (est&#x00e1; en el directorio <literal>etc/</literal>) a tu directorio <literal>src</literal>,
+                junto a <literal>hibernate.cfg.xml</literal>. Echa una mirada a la configuraci&#x00f3;n de
+                ejemplo y cambia los ajustes si te gusta tener una salida m&#x00e1;s verborr&#x00e1;gica.
+                Por defecto, s&#x00f3;lo se muestra el mensaje de arranque de Hibernate en la salida.
+            </para>
+
+            <para>
+                La infraestructura del tutorial est&#x00e1; completa, y estamos listos para hacer
+                alg&#x00fa;n trabajo real con Hibernate.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-workingpersistence">
+            <title>Cargando y almacenando objetos</title>
+
+            <para>
+                Finalmente, podemos usar Hibernate para cargar y almacenar objetos.
+                Escribimos una clase <literal>EventManager</literal> con un m&#x00e9;todo
+                <literal>main()</literal>:
+            </para>
+
+            <programlisting><![CDATA[import org.hibernate.Transaction;
+import org.hibernate.Session;
+
+import java.util.Date;
+
+public class EventManager {
+
+    public static void main(String[] args) {
+        EventManager mgr = new EventManager();
+
+        if (args[0].equals("store")) {
+            mgr.createAndStoreEvent("My Event", new Date());
+        }
+
+        HibernateUtil.sessionFactory.close();
+    }
+
+}]]></programlisting>
+
+            <para>
+                Leemos algunos argumentos de la l&#x00ed;nea de comandos, y si el primer
+                argumento es "store", creamos y almacenamos un nuevo Event:
+            </para>
+
+            <programlisting><![CDATA[private void createAndStoreEvent(String title, Date theDate) {
+    Session session = HibernateUtil.currentSession();
+    Transaction tx = session.beginTransaction();
+
+    Event theEvent = new Event();
+    theEvent.setTitle(title);
+    theEvent.setDate(theDate);
+
+    session.save(theEvent);
+
+    tx.commit();
+    HibernateUtil.closeSession();
+}]]></programlisting>
+
+            <para>
+                Creamos un nuevo objeto <literal>Event</literal>, y se lo damos a Hibernate.
+                Hibernate cuida ahora del SQL y ejecuta <literal>INSERT</literal>s en la base
+                de datos. Echemos una mirada al c&#x00f3;digo de manejo de <literal>Session</literal>
+                y <literal>Transaction</literal> antes de ejecutar esto.
+            </para>
+
+            <para>
+                Una <literal>Session</literal> es una sola unidad de trabajo. Podr&#x00ed;a sorprenderte
+                que tengamos una API adicional, <literal>Transaction</literal>. Esto implica que una unidad
+                de trabajo puede ser "m&#x00e1;s larga" que una sola transacci&#x00f3;n de base de datos;
+                imagina una unidad de trabajo que se abarca varios ciclos petici&#x00f3;n/respuesta HTTP
+                (por ejemplo, un di&#x00e1;logo asistente) en una aplicaci&#x00f3;n web. Separar las
+                transacciones de base de datos de "las unidades de trabajo de la aplicaci&#x00f3;n desde
+                el punto de vista del usuario" es uno de los conceptos b&#x00e1;sicos de dise&#x00f1;o de
+                Hibernate. Llamamos una unidad de trabajo larga <emphasis>Transacci&#x00f3;n de
+                Aplicaci&#x00f3;n</emphasis>, usualmente encapsulando varias transacciones de base de
+                datos m&#x00e1;s cortas. Por ahora mantendremos las cosas simples y asumiremos una
+                granularidad uno-a-uno entre una <literal>Session</literal> y una <literal>Transaction</literal>.
+            </para>
+
+            <para>
+                ¿Qu&#x00e9; es lo que hacen <literal>Transaction.begin()</literal> y <literal>commit()</literal>?
+                ¿D&#x00f3;nde est&#x00e1; el rollback en caso que algo vaya mal? La API de <literal>Transaction</literal>
+                de Hibernate es opcional realmente, pero la usamos por conveniencia y portabilidad. Si manejases
+                la transacci&#x00f3;n de base de datos por ti mismo (por ejemplo, llamando a 
+                <literal>session.connection.commit()</literal>), ligar&#x00ed;as el c&#x00f3;digo a un entorno
+                de despliegue particular, en este JDBC directo no manejado. Estableciendo la f&#x00e1;brica
+                de <literal>Transaction</literal> en tu configuraci&#x00f3;n de Hibernate puedes desplegar
+                tu capa de persistencia en cualquier sitio. Echa una mirada al <xref linkend="transactions"/>
+                para m&#x00e1;s informaci&#x00f3;n sobre manejo y demarcaci&#x00f3;n de transacciones.
+                Hemos saltado tambi&#x00e9;n cualquier manejo de excepciones y rollback en este ejemplo.
+            </para>
+
+            <para>
+                Para ejecutar la primera rutina tenemos que agregar un objetivo llamable al fichero
+                de construcci&#x00f3;n de Ant:
+            </para>
+
+            <programlisting><![CDATA[<target name="run" depends="compile">
+    <java fork="true" classname="EventManager" classpathref="libraries">
+        <classpath path="${targetdir}"/>
+        <arg value="${action}"/>
+    </java>
+</target>]]></programlisting>
+
+            <para>
+                El valor del argumento <literal>action</literal> es establecido por l&#x00ed;nea de
+                comandos al llamar al objetivo:
+            </para>
+
+            <programlisting><![CDATA[C:\hibernateTutorial\>ant run -Daction=store]]></programlisting>
+
+            <para>
+                Debes ver, despu&#x00e9;s de la compilaci&#x00f3;n, a Hibernate arrancando y, dependiendo
+                de tu configuraci&#x00f3;n mucha salida de registro (log). Al final encontrar&#x00e1;s
+                la siguiente l&#x00ed;nea:
+            </para>
+
+            <programlisting><![CDATA[[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)]]></programlisting>
+
+            <para>
+                Esta es la <literal>INSERT</literal> ejecutada por Hibernate, los signos de preguntas
+                representan par&#x00e1;metros de ligado JDBC. Para ver los valores ligados como
+                argumentos, o para reducir la verborragia del registro, chequea tu
+                <literal>log4j.properties</literal>.
+            </para>
+
+            <para>
+                Ahora quisi&#x00e9;ramos listar acontecimientos almacenados tambi&#x00e9;n,
+                as&#x00ed; que agregamos una opci&#x00f3;n al m&#x00e9;todo principal:
+            </para>
+
+            <programlisting><![CDATA[if (args[0].equals("store")) {
+    mgr.createAndStoreEvent("My Event", new Date());
+}
+else if (args[0].equals("list")) {
+    List events = mgr.listEvents();
+    for (int i = 0; i < events.size(); i++) {
+        Event theEvent = (Event) events.get(i);
+        System.out.println("Event: " + theEvent.getTitle() +
+                           " Time: " + theEvent.getDate());
+    }
+}]]></programlisting>
+
+            <para>
+                Agregamos tambi&#x00e9;n un nuevo m&#x00e9;todo <literal>listEvents()</literal>:
+            </para>
+
+            <programlisting><![CDATA[private List listEvents() {
+    Session session = HibernateUtil.currentSession();
+    Transaction tx = session.beginTransaction();
+
+    List result = session.createQuery("from Event").list();
+
+    tx.commit();
+    session.close();
+
+    return result;
+}]]></programlisting>
+
+            <para>
+                Lo que hacemos aqu&#x00ed; es usar una consulta HQL (Lenguaje de Consulta de Hibernate
+                o Hibernate Query Language) para cargar todos los objetos <literal>Event</literal>
+                existentes de la base de datos. Hibernate generar&#x00e1; el SQL apropiado, lo enviar&#x00e1;
+                a la base de datosy poblar&#x00e1; los objetos <literal>Event</literal> con datos.
+                Puedes, por supuesto, crear consultas m&#x00e1;s complejas con HQL.
+            </para>
+
+            <para>
+                Si ahora llamas a Ant con <literal>-Daction=list</literal>, debes ver los eventos
+                que has almacenado hasta ahora. Puede sorprenderte que esto no funcione, al menos
+                si has seguido este tutorial paso por paso; el resultado siempre estar&#x00e1;
+                vac&#x00ed;o. La razon de esto es la opci&#x00f3;n <literal>hbm2ddl.auto</literal>
+                en la configuraci&#x00f3;n de Hibernate: Hibernate recrear&#x00e1; la base de datos
+                en cada ejecuci&#x00f3;n. Deshabil&#x00ed;tala quitando la opci&#x00f3;n, y ver&#x00e1;s
+                resultados en tu listado despu&#x00e9;s que llames a la acci&#x00f3;n <literal>store</literal>
+                unas cuantas veces. La generaci&#x00f3;n y exportaci&#x00f3;n de esquema es &#x00fa;til
+                mayormente en testeo unitario.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="tutorial-associations">
+        <title>Part 2 - Mapeando asociaciones</title>
+
+        <para>
+            Hemos mapeado un clase de entidad persistente a una tabla. Construyamos sobre esto y agreguemos
+            algunas asociaciones de clase. Primero agregaremos personas a nuestra aplicaci&#x00f3;n,
+            y almacenaremos una lista de eventos en las que participan.
+        </para>
+
+        <sect2 id="tutorial-associations-mappinguser">
+            <title>Mapeando la clase Person</title>
+
+            <para>
+                El primer corte de la clase <literal>Person</literal> es simple:
+            </para>
+
+            <programlisting><![CDATA[public class Person {
+
+    private Long id;
+    private int age;
+    private String firstname;
+    private String lastname;
+
+    Person() {}
+
+    // Accessor methods for all properties, private setter for 'id'
+
+}]]></programlisting>
+
+            <para>
+                Crea un fichero de mapeo llamado <literal>Person.hbm.xml</literal>:
+            </para>
+
+            <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="Person" table="PERSON">
+        <id name="id" column="PERSON_ID">
+            <generator class="increment"/>
+        </id>
+        <property name="age"/>
+        <property name="firstname"/>
+        <property name="lastname"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+            <para>
+                Finalmente, agrega el nuevo mapeo a la configuraci&#x00f3;n de Hibernate:
+            </para>
+
+            <programlisting><![CDATA[        <mapping resource="Event.hbm.xml"/>
+        <mapping resource="Person.hbm.xml"/>
+]]></programlisting>
+
+            <para>
+                Crearemos ahora una asociaci&#x00f3;n entre estas dos entidades. Obviamente,
+                las personas pueden participar en eventos, y los eventos tienen participantes.
+                Las cuestiones de dise&#x00f1;o con que tenemos que tratar son: direccionalidad,
+                multiplicidad y comportamiento de colecci&#x00f3;n.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-unidirset">
+            <title>Una asociaci&#x00f3;n unidireccional basada en Set</title>
+
+            <para>
+                Agregaremos una colecci&#x00f3;n de eventos a la clase <literal>Person</literal>.
+                De esta forma podemos navegar facilmente a los eventos de una persona en particular,
+                sin ejecutar una consulta expl&#x00ed;cita, llamando a <literal>aPerson.getEvents()</literal>.
+                Usamos una colecci&#x00f3;n Java, un <literal>Set</literal>, porque la colecci&#x00f3;n no
+                contendr&#x00e1; elementos duplicados y el ordenamiento no nos es relevante.
+            </para>
+
+            <para>
+                Hasta ahora hemos dise&#x00f1;ado asociaciones unidireccionales multivaluadas, implementadas con un
+                <literal>Set</literal>. Escribamos el c&#x00f3;digo para esto en las clases Java y luego lo
+                mapeemos:
+            </para>
+
+            <programlisting><![CDATA[public class Person {
+
+    private Set events = new HashSet();
+
+    public Set getEvents() {
+        return events;
+    }
+
+    public void setEvents(Set events) {
+        this.events = events;
+    }
+}]]></programlisting>
+
+            <para>
+                Antes que mapeemos esta asociaci&#x00f3;n, piensa sobre el otro lado. Claramente, podemos
+                mantener esto solamente unidireccional. O podemos crear otra colecci&#x00f3;n en el
+                <literal>Event</literal>, si queremos ser capaces de navegarlos bidireccionalmente;
+                por ejemplo, <literal>anEvent.getParticipants()</literal>. Esta es una elecci&#x00f3;n
+                de dise&#x00f1;o que recae en ti, pero lo que est&#x00e1; claro de esta discusi&#x00f3;n
+                es la multiplicidad de la asociaci&#x00f3;n: "multi" valuada a ambos lados, llamamos a esto
+                una asociaci&#x00f3;n <emphasis>muchos-a-muchos</emphasis>. Por lo tanto, usamos un mapeo
+                many-to-many de Hibernate:
+            </para>
+
+            <programlisting><![CDATA[<class name="Person" table="PERSON">
+    <id name="id" column="PERSON_ID">
+        <generator class="increment"/>
+    </id>
+    <property name="age"/>
+    <property name="firstname"/>
+    <property name="lastname"/>
+
+    <set name="events" table="PERSON_EVENT">
+        <key column="PERSON_ID"/>
+        <many-to-many column="EVENT_ID" class="Event"/>
+    </set>
+
+</class>]]></programlisting>
+
+            <para>
+                Hibernate soporta todo tipo de mapeos de colecci&#x00f3;n, siendo el m&#x00e1;s com&#x00fa;n
+                un <literal>&lt;set&gt;</literal>. Para una asociaci&#x00f3;n muchos-a-muchos (o relaci&#x00f3;n
+                de entidad <emphasis>n:m</emphasis>), se necesita una tabla de asociaci&#x00f3;n. Cada fila en esta
+                tabla representa un enlace entre una persona y un evento. Esta tabla se configura con el atributo
+                <literal>table</literal> del elemento <literal>set</literal>. El nombre de la columna identificadora
+                en la asociaci&#x00f3;n, para el lado de la persona, se define con el elemento
+                <literal>&lt;key&gt;</literal>. El nombre de columna para el lado del evento se define con el atributo
+                <literal>column</literal> del <literal>&lt;many-to-many&gt;</literal>. Tambi&#x00e9;n tienes que decirle
+                a Hibernate la clase de los objetos en tu colecci&#x00f3;n (correcto: la clase del otro lado de la
+                colecci&#x00f3;n de referencias).
+            </para>
+
+            <para>
+                El esquema de base de datos para este mapeo es, por lo tanto:
+            </para>
+
+            <programlisting><![CDATA[
+    _____________        __________________
+   |             |      |                  |       _____________
+   |   EVENTS    |      |   PERSON_EVENT   |      |             |
+   |_____________|      |__________________|      |    PERSON   |
+   |             |      |                  |      |_____________|
+   | *EVENT_ID   | <--> | *EVENT_ID        |      |             |
+   |  EVENT_DATE |      | *PERSON_ID       | <--> | *PERSON_ID  |
+   |  TITLE      |      |__________________|      |  AGE        |
+   |_____________|                                |  FIRSTNAME  |
+                                                  |  LASTNAME   |
+                                                  |_____________|
+ ]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-working">
+            <title>Trabajando la asociaci&#x00f3;n</title>
+
+            <para>
+                Traigamos alguna gente y eventos juntos en un nuevo m&#x00e9;todo en
+                <literal>EventManager</literal>:
+            </para>
+
+            <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+    Session session = HibernateUtil.currentSession();
+    Transaction tx = session.beginTransaction();
+
+    Person aPerson = (Person) session.load(Person.class, personId);
+    Event anEvent = (Event) session.load(Event.class, eventId);
+
+    aPerson.getEvents().add(anEvent);
+
+    tx.commit();
+    HibernateUtil.closeSession();
+}]]></programlisting>
+
+            <para>
+                Despu&#x00e9;s de cargar una <literal>Person</literal> y un <literal>Event</literal>, simplemente
+                modifica la colecci&#x00f3;n usando sus m&#x00e9;todos normales. Como puedes ver, no hay una llamada
+                expl&#x00ed;cita a <literal>update()</literal> o <literal>save()</literal>. Hibernate detecta
+                autom&#x00e1;ticamente que la colecci&#x00f3;n ha sido modificada y necesita ser salvada. Esto
+                es llamado <emphasis>chequeo sucio autom&#x00f3;tico (automatic dirty checking)</emphasis>, y
+                tambi&#x00e9;n puedes intentarlo modificando el nombre de la propiedad de fecha de cualquiera de tus
+                objetos. Mientras est&#x00e9;n en estado <emphasis>persistente</emphasis>, esto es, ligados a una
+                <literal>Session</literal> de Hibernate particular (es decir, justo han sido cargados o almacenados
+                en una unidad de trabajo), Hibernate monitoriza cualquier cambio y ejecuta SQL en estilo
+                escribe-por-detr&#x00e1;s. El proceso de sincronizaci&#x00f3;n del estado de memoria con la base
+                de datos, usualmente s&#x00f3;lo al final de una unidad de trabajo,
+                es llamado <emphasis>limpieza (flushing)</emphasis>.
+            </para>
+
+            <para>
+                Podr&#x00ed;as, por supuesto, cargar persona y evento en unidades de trabajo diferentes. O
+                modificas un objeto fuera de una <literal>Session</literal>, cuando no est&#x00e1; en estado
+                persistente (si antes era persistente llamamos a este estado <emphasis>separado (detached)
+                </emphasis>). En c&#x00f3;digo (no muy realista), esto se ver&#x00ed;a como sigue:
+            </para>
+
+            <programlisting><![CDATA[    private void addPersonToEvent(Long personId, Long eventId) {
+
+        Session session = HibernateUtil.currentSession();
+        Transaction tx = session.beginTransaction();
+
+        Person aPerson = (Person) session.load(Person.class, personId);
+        Event anEvent = (Event) session.load(Event.class, eventId);
+
+        tx.commit();
+        HibernateUtil.closeSession();
+
+        aPerson.getEvents().add(anEvent); // aPerson is detached
+
+        Session session2 = HibernateUtil.currentSession();
+        Transaction tx2 = session.beginTransaction();
+
+        session2.update(aPerson); // Reattachment of aPerson
+
+        tx2.commit();
+        HibernateUtil.closeSession();
+    }
+]]></programlisting>
+
+            <para>
+                La llamada a <literal>update</literal> hace a un objeto persistente de nuevo, podr&#x00ed;as
+                decir que la liga a una nueva unidad de trabajo, de modo que cualquier modificaci&#x00f3;n que
+                le hagas mientras est&#x00e9; separado puede ser salvada a base de datos.
+            </para>
+
+            <para>
+                Bueno, esto no es muy usado en nuestra situaci&#x00f3;n actual, pero es un concepto
+                importante que puedes dise&#x00f1;ar en tu propia aplicaci&#x00f3;n. Por ahora, completa
+                este ejercicio agregando una nueva acci&#x00f3;n al m&#x00e9;todo main de
+                <literal>EventManager</literal> y ll&#x00e1;mala desde la l&#x00ed;nea de comandos.
+                Si necesitas los identificadores de una persona o evento, el m&#x00e9;todo
+                <literal>save()</literal> los devuelve.
+            </para>
+
+            <para>
+                Esto fue un ejemplo de una asociaci&#x00f3;n entre dos clases igualmente importantes, dos entidades.
+                Como se ha mencionado anteriormente, hay otras clases y tipos en un modelo t&#x00ed;pico,
+                usualmente "menos importantes". Algunos ya los habr&#x00e1;s visto, como un <literal>int</literal>
+                o un <literal>String</literal>. Llamamos a estas clases <emphasis>tipos de valor (value types)</emphasis>,
+                y sus instancias <emphasis>dependen</emphasis> de una entidad en particular. Las instancias de estos
+                tipos no tienen su propia identidad, ni son compartidas entre entidades (dos personas no referencian
+                el mismo objeto <literal>firstname</literal>, incluso si tuvieran el mismo primer nombre). Por supuesto,
+                los tipos de valor no s&#x00f3;lo pueden encontrarse en el JDK (de hecho, en una aplicaci&#x00f3;n
+                Hibernate todas las clases del JDK son consideradas tipos de valor), sino que adem&#x00e1;s puedes
+                escribir por ti mismo clases dependientes, por ejemplo, <literal>Address</literal> o
+                <literal>MonetaryAmount</literal>.
+            </para>
+
+            <para>
+                Tambi&#x00e9;n puedes dise&#x00f1;ar una colecci&#x00f3;n de tipos de valor. Esto es conceptualmente
+                muy diferente de una colecci&#x00f3;n de referencias a otras entidades, pero se ve casi lo mismo en
+                Java.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-valuecollections">
+            <title>Colecci&#x00f3;n de valores</title>
+
+            <para>
+                Agregamos una colecci&#x00f3;n de objetos tipificados en valor a la entidad <literal>Person</literal>.
+                Queremos almacenar direcciones de email, de modo que el tipo que usamos es <literal>String</literal>,
+                y la colecci&#x00f3;n es nuevamente un <literal>Set</literal>:
+            </para>
+            <programlisting><![CDATA[private Set emailAddresses = new HashSet();
+
+public Set getEmailAddresses() {
+    return emailAddresses;
+}
+
+public void setEmailAddresses(Set emailAddresses) {
+    this.emailAddresses = emailAddresses;
+}]]></programlisting>
+
+            <para>
+                El mapeo de este <literal>Set</literal>:
+            </para>
+
+            <programlisting><![CDATA[<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
+    <key column="PERSON_ID"/>
+    <element type="string" column="EMAIL_ADDR"/>
+</set>]]></programlisting>
+
+            <para>
+                La diferencia comparada con el mapeo anterior es la parte <literal>element</literal>, que le dice
+                a Hibernate que la colecci&#x00f3;n no contiene referencias a otra entidad, sino una colecci&#x00f3;n
+                de elementos de tipo <literal>String</literal> (el nombre en min&#x00fa;sculas te dice que es un
+                tipo/conversor de mapeo de Hibernate). Una vez m&#x00e1;s, el atributo <literal>table</literal> del
+                elemento <literal>set</literal> determina el nombre de la tabla para la colecci&#x00f3;n. El elemento
+                <literal>key</literal> define el nombre de la columna clave for&#x00e1;nea en la tabla de colecci&#x00f3;n.
+                El atributo <literal>column</literal> en el elemento <literal>element</literal> define el nombre de
+                columna donde realmente ser&#x00e1;n almacenados los valores <literal>String</literal>.
+            </para>
+
+            <para>
+                Echa una mirada al esquema actualizado:
+            </para>
+
+            <programlisting><![CDATA[
+  _____________        __________________
+ |             |      |                  |       _____________
+ |   EVENTS    |      |   PERSON_EVENT   |      |             |       ___________________
+ |_____________|      |__________________|      |    PERSON   |      |                   |
+ |             |      |                  |      |_____________|      | PERSON_EMAIL_ADDR |
+ | *EVENT_ID   | <--> | *EVENT_ID        |      |             |      |___________________|
+ |  EVENT_DATE |      | *PERSON_ID       | <--> | *PERSON_ID  | <--> |  *PERSON_ID       |
+ |  TITLE      |      |__________________|      |  AGE        |      |  *EMAIL_ADDR      |
+ |_____________|                                |  FIRSTNAME  |      |___________________|
+                                                |  LASTNAME   |
+                                                |_____________|
+ ]]></programlisting>
+
+            <para>
+                Puedes ver que la clave primaria de la tabla de colecci&#x00f3;n es de hecho una clave
+                compuesta, usando ambas columnas. Esto implica tambi&#x00e9;n que no pueden haber
+                direcciones de email duplicadas por persona, que es exactamente la sem&#x00e1;ntica
+                que necesitamos para un conjunto en Java.
+            </para>
+
+            <para>
+                Puedes ahora intentar y agregar elementos a esta colecci&#x00f3;n, al igual que
+                hicimos antes enlazando personas y eventos. Es el mismo c&#x00f3;digo en Java.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-bidirectional">
+            <title>Asociaciones bidireccionales</title>
+
+            <para>
+                A continuacion vamos a mapear una asociaci&#x00f3;n bidireccional, haciendo que la
+                asociaci&#x00f3;n entre persona y evento funcione desde ambos lados en Java. Por supuesto,
+                el esquema de base de datos no cambia; todav&#x00ed;a necesitamos multiplicidad muchos-a-muchos.
+                Una base de datos relacional es m&#x00e1;s flexible que un lenguaje de programaci&#x00f3;n
+                de red, as&#x00ed; que no necesita nada parecido a una direcci&#x00f3;n de navegaci&#x00f3;n;
+                los datos pueden ser vistos y recuperados en cualquier forma posible.
+            </para>
+
+            <para>
+                Primero agrega una colecci&#x00f3;n de participantes a la clase de eventos
+                <literal>Event</literal>:
+            </para>
+
+            <programlisting><![CDATA[private Set participants = new HashSet();
+
+public Set getParticipants() {
+    return participants;
+}
+
+public void setParticipants(Set participants) {
+    this.participants = participants;
+}]]></programlisting>
+
+            <para>
+                Ahora mapea este lado de la asociaci&#x00f3;n tambi&#x00e9;n, en
+                <literal>Event.hbm.xml</literal>.
+            </para>
+
+            <programlisting><![CDATA[<set name="participants" table="PERSON_EVENT" inverse="true">
+    <key column="EVENT_ID"/>
+    <many-to-many column="PERSON_ID" class="Person"/>
+</set>]]></programlisting>
+
+            <para>
+                Como ves, estos son mapeos normales de <literal>set</literal> en ambos documentos de
+                mapeo. Nota que los nombres de columnas en <literal>key</literal> y
+                <literal>many-to-many</literal> fueron permutados en ambos documentos de mapeo. Aqu&#x00ed; la
+                adici&#x00f3;n m&#x00e1;s importante es el atributo <literal>inverse="true"</literal> en el
+                elemento <literal>set</literal> del mapeo de colecci&#x00f3;n de <literal>Event</literal>.
+            </para>
+
+            <para>
+                Lo que esto significa es que Hibernate debe tomar el otro lado - la clase <literal>Person</literal> -
+                cuando necesite descubrir informaci&#x00f3;n sobre el enlace entre las dos. Esto ser&#x00e1; mucho
+                m&#x00e1;s f&#x00e1;cil de entender una vez que veas c&#x00f3;mo se crea el enlace bidireccional
+                entre nuestras dos entidades.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-usingbidir">
+            <title>Trabajando enlaces bidireccionales</title>
+
+            <para>
+                Primero, ten en mente que Hhibernate no afecta la sem&#x00e1;ntica normal de Java. ¿C&#x00f3;mo
+                hemos creado un enlace entre una <literal>Person</literal> y un <literal>Event</literal> en el
+                ejemplo unidireccional? Hemos agregado una instancia de <literal>Event</literal> a la colecci&#x00f3;n
+                de referencias de eventos de una instancia de <literal>Person</literal>. De modo que, obviamente,
+                si queremos que este enlace funcione bidireccionalmente, tenemos que hacer lo mismo del otro lado,
+                agregando una referencia a <literal>Person</literal> a la colecci&#x00f3;n en un <literal>Event</literal>.
+                Este "establecer el enlace a ambos lados" es absolutamente necesario y nunca debes olvidar hacerlo.
+            </para>
+
+            <para>
+                Muchos desarrolladores programan a la defensiva y crean m&#x00e9;todos de
+                manejo de un enlace para establecer correctamente ambos lados, por ejemplo
+                en <literal>Person</literal>:
+            </para>
+
+            <programlisting><![CDATA[protected Set getEvents() {
+    return events;
+}
+
+protected void setEvents(Set events) {
+    this.events = events;
+}
+
+public void addToEvent(Event event) {
+    this.getEvents().add(event);
+    event.getParticipants().add(this);
+}
+
+public void removeFromEvent(Event event) {
+    this.getEvents().remove(event);
+    event.getParticipants().remove(this);
+}]]></programlisting>
+
+            <para>
+                Nota que los m&#x00e9;todos get y set para esta colecci&#x00f3;n son ahora protegidos. Esto le
+                permite a clases en el mismo paquete y a subclases acceder a&#x00fa;n a los m&#x00e9;todos, pero
+                previene a cualquier otro de ensuciarse con la colecci&#x00f3;n directamente (bueno, casi).
+                Probablemente debas hacer lo mismo con la colecci&#x00f3;n al otro lado.
+            </para>
+
+            <para>
+                Y ¿qu&#x00e9; del atributo de mapeo <literal>inverse</literal>?  Para ti, y para Java, un enlace
+                bidireccional es simplemente cuesti&#x00f3;n de establecer correctamente las referencias a ambos
+                lados. Hibernate, sin embargo, no tiene suficiente informaci&#x00f3;n para arreglar correctamente
+                sentencias <literal>INSERT</literal> y <literal>UPDATE</literal> de SQL (para evitar violaci&#x00f3;n
+                de restricciones), y necesita alguna ayuda para manejar asociaciones bidireccionales apropiadamente.
+                El hacer un lado de la asociaci&#x00f3;n <literal>inverse</literal> le dice a Hibernate que basicamente
+                lo ignore, que lo considere un <emphasis>espejo</emphasis> del otro lado. Esto es todo lo necesario para
+                que Hibernate resuelva todas las incidencias al transformar un modelo de navegaci&#x00f3;n direccional a
+                un esquema SQL de base de datos. Las reglas que tienes que recordar son directas: Todas las asociaciones
+                bidireccionales necesitan uno de los lados como <literal>inverse</literal>. En una asociaci&#x00f3;n
+                uno-a-muchos debe ser el lado-de-muchos. En una asociaci&#x00f3;n muchos-a-muchos, puedes tomar cualquier
+                lado, no hay diferencia.
+            </para>
+<!--
+            <para>
+                In the next section we integrate Hibernate with Tomcat and WebWork - the <literal>EventManager</literal>
+                doesn't scale anymore with our growing application.
+            </para>
+-->
+        </sect2>
+    </sect1>
+
+    <sect1 id="tutorial-summary">
+        <title>Summary</title>
+
+        <para>
+            Este tutorial cubri&#x00f3; los fundamentos de escribir una simple aplicaci&#x00f3;n independiente
+            de Hibernate.
+        </para>
+
+        <para>
+            Si ya te sientes confidente con Hibernate, contin&#x00fa;a navegando a trav&#x00e9;s de la
+            tabla de contenidos de la documentaci&#x00f3;n de referencia para los temas que encuentres
+            interesantes. Los m&#x00e1;s consultados son procesamiento transaccional (<xref linkend="transactions"/>),
+            rendimiento de recuperaci&#x00f3;n (<xref linkend="performance"/>), o el uso de la API
+            (<xref linkend="objectstate"/>) y las funcionalidades de consulta (<xref linkend="objectstate-querying"/>).
+        </para>
+
+        <para>
+            No olvides chequear el sitio web de Hibernate por m&#x00e1;s (especializados) tutoriales.
+        </para>
+
+    </sect1>
+
+</chapter>
\ No newline at end of file

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/content/xml.xml (from rev 12794, core/trunk/documentation/manual/es-ES/src/main/docbook/modules/xml.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/content/xml.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/content/xml.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,282 @@
+<chapter id="xml">
+    <title>Mapeo XML</title>
+
+    <para><emphasis>
+        Nota que esta es una funcionalidad experimental en Hibernate 3.0 y está
+        bajo un desarrollo extremadamente activo.
+    </emphasis></para>
+
+    <sect1 id="xml-intro" revision="1">
+        <title>Trabajando con datos XML</title>
+
+        <para>
+            Hibernate te permite trabajar con datos XML persistentes en casi la misma forma
+            que trabajas con POJOs persistentes. Un árbol XML analizado (parsed) puede ser
+            pensado como sólo otra forma de representar los datos relacionales a nivel de objetos,
+            en vez de POJOs.
+        </para>
+
+        <para>
+            Hibernate soporta dom4j como API para manipular árboles XML. Puedes escribir
+            consultas que traigan árboles dom4j de la base de datos y tener cualquier modificación
+            que hagas al árbol sincronizada automáticamente a la base de datos. Puedes incluso tomar 
+            un documento XML, analizarlo usando dom4j, y escribirlo a la base de datos con cualquiera
+            de las operaciones básicas de Hibernate: <literal>persist(), saveOrUpdate(), merge(),
+            delete(), replicate()</literal> (la fusión no está aún soportada).
+        </para>
+
+        <para>
+            Esta funcionalidad tiene muchas aplicaciones incluyendo la importación/exportación de datos,
+            externalización de datos de entidad vía JMS o SOAP y reportes basados en XSLT.
+        </para>
+        
+        <para>
+            Un solo mapeo puede ser usado para mapear simultáneamente las propiedades de una clase y los nodos de un
+            documento XML a la base de datos, o, si no hay ninguna clase a mapear, puede ser usado para mapear sólo
+            el XML.
+        </para>
+        
+        <sect2 id="xml-intro-mapping">
+            <title>Especificando los mapeos de XML y de clase juntos</title>
+
+            <para>
+                He aquí un ejemplo de mapear un POJO y XML simultáneamente:
+            </para>
+            
+            <programlisting><![CDATA[<class name="Account" 
+        table="ACCOUNTS" 
+        node="account">
+        
+    <id name="accountId" 
+            column="ACCOUNT_ID" 
+            node="@id"/>
+            
+    <many-to-one name="customer" 
+            column="CUSTOMER_ID" 
+            node="customer/@id" 
+            embed-xml="false"/>
+            
+    <property name="balance" 
+            column="BALANCE" 
+            node="balance"/>
+            
+    ...
+    
+</class>]]></programlisting>
+        </sect2>
+        
+        <sect2 id="xml-onlyxml">
+            <title>Especificando sólo un mapeo XML</title>
+
+            <para>
+                He aquí un ejemplo donde no hay ninguna clase POJO:
+            </para>
+            
+            <programlisting><![CDATA[<class entity-name="Account" 
+        table="ACCOUNTS" 
+        node="account">
+        
+    <id name="id" 
+            column="ACCOUNT_ID" 
+            node="@id" 
+            type="string"/>
+            
+    <many-to-one name="customerId" 
+            column="CUSTOMER_ID" 
+            node="customer/@id" 
+            embed-xml="false" 
+            entity-name="Customer"/>
+            
+    <property name="balance" 
+            column="BALANCE" 
+            node="balance" 
+            type="big_decimal"/>
+            
+    ...
+    
+</class>]]></programlisting>
+        
+            <para>
+                Este mapeo te permite acceder a los datos como un árbol dom4j, o como un grafo de pares nombre/valor de
+                propiedad (<literal>Map</literal>s de Java). Los nombres de propiedades son construcciones puramente
+                lógicas a las que se puede hacer referencia en consultas HQL.
+            </para>
+
+        </sect2>
+        
+     </sect1>
+     
+    <sect1 id="xml-mapping" revision="1">
+        <title>Mapeo de metadatos XML</title>
+
+        <para>
+            Muchos elementos de mapeo de Hibernate aceptan el atributo <literal>node</literal>. Esto te permite espcificar
+            el nombre de un atributo o elemento XML que contenga los datos de la propiedad o entidad. El formato del
+            atributo <literal>node</literal> debe ser uno de los siguientes:
+        </para>
+        
+        <itemizedlist spacing="compact">
+        <listitem>
+            <para><literal>"element-name"</literal> - mapea al elemento XML mencionado</para>
+        </listitem>
+        <listitem>
+            <para><literal>"@attribute-name"</literal> - mapea al atributo XML mencionado</para>
+        </listitem>
+        <listitem>
+            <para><literal>"."</literal> - mapea al elemento padre</para>
+        </listitem>
+        <listitem>
+            <para>
+                <literal>"element-name/@attribute-name"</literal> - 
+                mapea al atributo mencionado del elemento mencionado
+            </para>
+        </listitem>
+        </itemizedlist>
+        
+        <para>
+            Para las colecciones y asociaciones monovaluadas, existe un atributo adicional <literal>embed-xml</literal>.
+            Si <literal>embed-xml="true"</literal>, que es el valor por defecto, el árbol XML para la entidad
+            asociada (o colección de tipo de valor) será embebida directamente en el árbol XML para la entidad que
+            posee la asociación. En otro caso, si <literal>embed-xml="false"</literal>, sólo el valor identificador
+            referenciado aparecerá en el XML para asociaciones de punto único y para las colecciones simplemente
+            no aparecerá en absoluto.
+        </para>
+        
+        <para>
+            ¡Debes ser cuidadoso de no dejar <literal>embed-xml="true"</literal> para demasiadas asociaciones,
+            ya que XML no trata bien la circularidad!
+        </para>
+        
+        <programlisting><![CDATA[<class name="Customer" 
+        table="CUSTOMER" 
+        node="customer">
+        
+    <id name="id" 
+            column="CUST_ID" 
+            node="@id"/>
+            
+    <map name="accounts" 
+            node="." 
+            embed-xml="true">
+        <key column="CUSTOMER_ID" 
+                not-null="true"/>
+        <map-key column="SHORT_DESC" 
+                node="@short-desc" 
+                type="string"/>
+        <one-to-many entity-name="Account"
+                embed-xml="false" 
+                node="account"/>
+    </map>
+    
+    <component name="name" 
+            node="name">
+        <property name="firstName" 
+                node="first-name"/>
+        <property name="initial" 
+                node="initial"/>
+        <property name="lastName" 
+                node="last-name"/>
+    </component>
+    
+    ...
+    
+</class>]]></programlisting>
+
+        <para>
+            en este caso, hemos decidido embeber la colección de ids de cuenta, pero no los datos reales de cuenta.
+            La siguiente consulta HQL:
+        </para>
+        
+        <programlisting><![CDATA[from Customer c left join fetch c.accounts where c.lastName like :lastName]]></programlisting>
+        
+        <para>
+            devolvería conjuntos de datos como estos:
+        </para>
+        
+        <programlisting><![CDATA[<customer id="123456789">
+    <account short-desc="Savings">987632567</account>
+    <account short-desc="Credit Card">985612323</account>
+    <name>
+        <first-name>Gavin</first-name>
+        <initial>A</initial>
+        <last-name>King</last-name>
+    </name>
+    ...
+</customer>]]></programlisting>
+
+        <para>
+            Si estableces <literal>embed-xml="true"</literal> en el mapeo <literal>&lt;one-to-many&gt;</literal>, los datos
+            podrían verse así:
+        </para>
+        
+        <programlisting><![CDATA[<customer id="123456789">
+    <account id="987632567" short-desc="Savings">
+        <customer id="123456789"/>
+        <balance>100.29</balance>
+    </account>
+    <account id="985612323" short-desc="Credit Card">
+        <customer id="123456789"/>
+        <balance>-2370.34</balance>
+    </account>
+    <name>
+        <first-name>Gavin</first-name>
+        <initial>A</initial>
+        <last-name>King</last-name>
+    </name>
+    ...
+</customer>]]></programlisting>
+       
+    </sect1>
+    
+    
+    <sect1 id="xml-manipulation" revision="1">
+        <title>Manipulando datos XML</title>
+        
+        <para>
+            Vamos a releer y actualizar documentos XML en la aplicación. Hacemos esto obteniendo una sesión dom4j:
+        </para>
+        
+       <programlisting><![CDATA[Document doc = ....;
+       
+Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+List results = dom4jSession
+    .createQuery("from Customer c left join fetch c.accounts where c.lastName like :lastName")
+    .list();
+for ( int i=0; i<results.size(); i++ ) {
+    //add the customer data to the XML document
+    Element customer = (Element) results.get(i);
+    doc.add(customer);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+       
+       <programlisting><![CDATA[Session session = factory.openSession();
+Session dom4jSession = session.getSession(EntityMode.DOM4J);
+Transaction tx = session.beginTransaction();
+
+Element cust = (Element) dom4jSession.get("Customer", customerId);
+for ( int i=0; i<results.size(); i++ ) {
+    Element customer = (Element) results.get(i);
+    //change the customer name in the XML and database
+    Element name = customer.element("name");
+    name.element("first-name").setText(firstName);
+    name.element("initial").setText(initial);
+    name.element("last-name").setText(lastName);
+}
+
+tx.commit();
+session.close();]]></programlisting>
+
+        <para>
+            Es extremadamente útil combinar esta funcionalidad con la operación <literal>replicate()</literal>
+            de Hibernate para implementar la importación/exportación de datos basada en XML.
+        </para>
+       
+    </sect1>
+     
+</chapter>
+

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/AuthorWork.png (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/AuthorWork.png)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/AuthorWork.zargo (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/AuthorWork.zargo)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/CustomerOrderProduct.png (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/CustomerOrderProduct.png)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/CustomerOrderProduct.zargo (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/CustomerOrderProduct.zargo)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/EmployerEmployee.png (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/EmployerEmployee.png)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/EmployerEmployee.zargo (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/EmployerEmployee.zargo)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/full_cream.png (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/full_cream.png)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/full_cream.svg (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/full_cream.svg)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/images/full_cream.svg	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/images/full_cream.svg	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,429 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+  xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   width="354.331"
+   height="336.614"
+   id="svg1">
+  <defs
+     id="defs3">
+    <linearGradient
+       x1="0"
+       y1="0"
+       x2="1"
+       y2="0"
+       id="linearGradient127"
+       gradientUnits="objectBoundingBox"
+       spreadMethod="pad">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop128" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="1"
+         id="stop129" />
+    </linearGradient>
+    <linearGradient
+       x1="0"
+       y1="0"
+       x2="1"
+       y2="0"
+       id="linearGradient130"
+       xlink:href="#linearGradient127"
+       gradientUnits="objectBoundingBox"
+       spreadMethod="pad" />
+    <radialGradient
+       cx="0.5"
+       cy="0.5"
+       fx="0.5"
+       fy="0.5"
+       r="0.5"
+       id="radialGradient131"
+       xlink:href="#linearGradient127"
+       gradientUnits="objectBoundingBox"
+       spreadMethod="pad" />
+  </defs>
+  <g
+     transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+     style="font-size:12;"
+     id="g659">
+    <rect
+       width="212.257"
+       height="57.2441"
+       x="17.9576"
+       y="100.132"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect137" />
+    <rect
+       width="285.502"
+       height="118.523"
+       x="13.4238"
+       y="95.9309"
+       transform="matrix(0.743454,0,0,0.482981,6.46949,52.2178)"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect132" />
+  </g>
+  <rect
+     width="325.86"
+     height="63.6537"
+     x="17.4083"
+     y="15.194"
+     style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect136" />
+  <rect
+     width="325.86"
+     height="63.6537"
+     x="13.6713"
+     y="12.4966"
+     style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect126" />
+  <g
+     transform="matrix(1.14345,0,0,0.729078,-1.67818,105.325)"
+     style="font-size:12;"
+     id="g164">
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="16.6979"
+       y="222.966"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect138" />
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="14.7335"
+       y="221.002"
+       transform="translate(-1.30962,-1.30992)"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect133" />
+  </g>
+  <text
+     x="170.824753"
+     y="58.402939"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text183">
+    <tspan
+       x="170.824997"
+       y="58.402901"
+       id="tspan360">
+Application</tspan>
+  </text>
+  <text
+     x="178.076340"
+     y="364.281433"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text197">
+    <tspan
+       x="178.076004"
+       y="364.281006"
+       id="tspan421">
+Database</tspan>
+  </text>
+  <text
+     x="68.605331"
+     y="138.524582"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text216">
+    <tspan
+       x="68.605301"
+       y="138.524994"
+       id="tspan384">
+SessionFactory</tspan>
+  </text>
+  <rect
+     width="67.0014"
+     height="101.35"
+     x="196.927"
+     y="89.2389"
+     style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect387" />
+  <rect
+     width="67.0014"
+     height="101.35"
+     x="194.633"
+     y="86.4389"
+     style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect388" />
+  <text
+     x="249.108841"
+     y="173.885559"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text389">
+    <tspan
+       x="249.108994"
+       y="173.886002"
+       id="tspan392">
+Session</tspan>
+  </text>
+  <rect
+     width="73.0355"
+     height="101.35"
+     x="270.995"
+     y="90.0018"
+     style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect395" />
+  <rect
+     width="73.0355"
+     height="101.35"
+     x="267.869"
+     y="87.2018"
+     style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect396" />
+  <text
+     x="328.593658"
+     y="174.715622"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text397">
+    <tspan
+       x="328.593994"
+       y="174.716003"
+       id="tspan563">
+Transaction</tspan>
+  </text>
+  <g
+     transform="matrix(0.29544,0,0,0.397877,9.70533,103.96)"
+     style="font-size:12;"
+     id="g565">
+    <rect
+       width="285.502"
+       height="118.523"
+       x="16.6979"
+       y="99.2053"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect566" />
+    <rect
+       width="285.502"
+       height="118.523"
+       x="13.4238"
+       y="95.9309"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect567" />
+  </g>
+  <text
+     x="25.592752"
+     y="204.497803"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text568">
+    <tspan
+       x="25.592800"
+       y="204.498001"
+       id="tspan662">
+TransactionFactory</tspan>
+  </text>
+  <g
+     transform="matrix(0.298082,0,0,0.397877,99.6898,103.96)"
+     style="font-size:12;"
+     id="g573">
+    <rect
+       width="285.502"
+       height="118.523"
+       x="16.6979"
+       y="99.2053"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect574" />
+    <rect
+       width="285.502"
+       height="118.523"
+       x="13.4238"
+       y="95.9309"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect575" />
+  </g>
+  <text
+     x="134.030670"
+     y="205.532791"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:10;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text576">
+    <tspan
+       x="134.031006"
+       y="205.533005"
+       id="tspan664">
+ConnectionProvider</tspan>
+  </text>
+  <g
+     transform="matrix(1.14345,0,0,0.729078,-1.67818,38.9539)"
+     style="font-size:12;"
+     id="g587">
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="16.6979"
+       y="222.966"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect588" />
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="14.7335"
+       y="221.002"
+       transform="translate(-1.30962,-1.30992)"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect589" />
+  </g>
+  <rect
+     width="90.951"
+     height="44.4829"
+     x="25.6196"
+     y="206.028"
+     style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect594" />
+  <rect
+     width="90.951"
+     height="44.4829"
+     x="24.4229"
+     y="204.135"
+     style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect595" />
+  <text
+     x="85.575645"
+     y="282.300354"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+     id="text596">
+    <tspan
+       x="85.575600"
+       y="282.299988"
+       id="tspan607">
+JNDI</tspan>
+  </text>
+  <rect
+     width="90.951"
+     height="44.4829"
+     x="236.937"
+     y="206.791"
+     style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect610" />
+  <rect
+     width="90.951"
+     height="44.4829"
+     x="235.741"
+     y="204.898"
+     style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect611" />
+  <text
+     x="342.093201"
+     y="283.226410"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+     id="text612">
+    <tspan
+       x="342.092987"
+       y="283.226013"
+       id="tspan621">
+JTA</tspan>
+  </text>
+  <rect
+     width="90.951"
+     height="44.4829"
+     x="130.134"
+     y="206.791"
+     style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect616" />
+  <rect
+     width="90.951"
+     height="44.4829"
+     x="128.937"
+     y="204.898"
+     style="font-size:12;fill:#b3b3b3;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect617" />
+  <text
+     x="212.445343"
+     y="283.226410"
+     transform="scale(0.823795,0.823795)"
+     style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+     id="text618">
+    <tspan
+       x="212.445007"
+       y="283.226013"
+       id="tspan623">
+JDBC</tspan>
+  </text>
+  <g
+     transform="matrix(0.823795,0,0,0.823795,0.120302,6.19341)"
+     style="font-size:12;"
+     id="g637">
+    <g
+       transform="matrix(0.499515,0,0,0.415467,-0.237339,5.61339)"
+       id="g167">
+      <rect
+         width="199.065"
+         height="61.5532"
+         x="61.8805"
+         y="68.4288"
+         style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+         id="rect134" />
+      <rect
+         width="199.065"
+         height="61.5532"
+         x="59.2613"
+         y="65.8095"
+         style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+         id="rect135" />
+    </g>
+    <text
+       x="33.749969"
+       y="50.589706"
+       style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+       id="text188">
+      <tspan
+         x="33.750000"
+         y="50.589699"
+         id="tspan635">
+Transient Objects</tspan>
+    </text>
+  </g>
+  <g
+     transform="matrix(0.823795,0,0,0.823795,0.120302,5.25349)"
+     style="font-size:12;"
+     id="g644">
+    <g
+       transform="matrix(0.297486,0,0,0.516482,230.251,36.9178)"
+       id="g364">
+      <rect
+         width="199.065"
+         height="61.5532"
+         x="61.8805"
+         y="68.4288"
+         style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+         id="rect365" />
+      <rect
+         width="199.065"
+         height="61.5532"
+         x="59.2613"
+         y="65.8095"
+         style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+         id="rect366" />
+    </g>
+    <text
+       x="277.123230"
+       y="85.155571"
+       style="font-size:11;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+       id="text367">
+      <tspan
+         x="277.122986"
+         y="85.155602"
+         id="tspan631">
+Persistent</tspan>
+      <tspan
+         x="277.122986"
+         y="96.155602"
+         id="tspan633">
+Objects</tspan>
+    </text>
+  </g>
+</svg>

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/hibernate_logo_a.png (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/hibernate_logo_a.png)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/lite.png (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/lite.png)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/lite.svg (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/lite.svg)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/images/lite.svg	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/images/lite.svg	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,334 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+  xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   width="318.898"
+   height="248.031"
+   id="svg1">
+  <defs
+     id="defs3">
+    <linearGradient
+       x1="0"
+       y1="0"
+       x2="1"
+       y2="0"
+       id="linearGradient127"
+       gradientUnits="objectBoundingBox"
+       spreadMethod="pad">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop128" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="1"
+         id="stop129" />
+    </linearGradient>
+    <linearGradient
+       x1="0"
+       y1="0"
+       x2="1"
+       y2="0"
+       id="linearGradient130"
+       xlink:href="#linearGradient127"
+       gradientUnits="objectBoundingBox"
+       spreadMethod="pad" />
+    <radialGradient
+       cx="0.5"
+       cy="0.5"
+       fx="0.5"
+       fy="0.5"
+       r="0.5"
+       id="radialGradient131"
+       xlink:href="#linearGradient127"
+       gradientUnits="objectBoundingBox"
+       spreadMethod="pad" />
+  </defs>
+  <rect
+     width="291.837"
+     height="57.0074"
+     x="17.3169"
+     y="18.646"
+     style="font-size:12;fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect136" />
+  <rect
+     width="291.837"
+     height="57.0074"
+     x="13.9703"
+     y="16.2302"
+     style="font-size:12;fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+     id="rect126" />
+  <g
+     transform="matrix(0.326107,0,0,0.765831,9.59261,8.98517)"
+     style="font-size:12;"
+     id="g161">
+    <rect
+       width="285.502"
+       height="118.523"
+       x="16.6979"
+       y="99.2053"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect137" />
+    <rect
+       width="285.502"
+       height="118.523"
+       x="13.4238"
+       y="95.9309"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect132" />
+  </g>
+  <g
+     transform="matrix(1.02406,0,0,0.652953,0.223384,39.9254)"
+     style="font-size:12;"
+     id="g164">
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="16.6979"
+       y="222.966"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect138" />
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="14.7335"
+       y="221.002"
+       transform="translate(-1.30962,-1.30992)"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect133" />
+  </g>
+  <g
+     transform="matrix(0.449834,0,0,0.338463,-3.15909,9.73319)"
+     style="font-size:12;"
+     id="g167">
+    <rect
+       width="199.065"
+       height="61.5532"
+       x="61.8805"
+       y="68.4288"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect134" />
+    <rect
+       width="199.065"
+       height="61.5532"
+       x="59.2613"
+       y="65.8095"
+       style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect135" />
+  </g>
+  <text
+     x="302.277679"
+     y="65.943230"
+     transform="scale(0.73778,0.73778)"
+     style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text183">
+    <tspan
+       x="302.277954"
+       y="65.943184"
+       id="tspan360">
+Application</tspan>
+  </text>
+  <text
+     x="36.235924"
+     y="63.796055"
+     transform="scale(0.73778,0.73778)"
+     style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text188">
+    <tspan
+       x="36.235950"
+       y="63.796051"
+       id="tspan427">
+Transient Objects</tspan>
+  </text>
+  <text
+     x="180.416245"
+     y="290.543701"
+     transform="scale(0.73778,0.73778)"
+     style="font-size:18;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text197">
+    <tspan
+       x="180.415939"
+       y="290.543549"
+       id="tspan421">
+Database</tspan>
+  </text>
+  <text
+     x="25.037701"
+     y="179.154755"
+     transform="scale(0.73778,0.73778)"
+     style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text216">
+    <tspan
+       x="25.037655"
+       y="179.154648"
+       id="tspan384">
+SessionFactory</tspan>
+  </text>
+  <g
+     transform="matrix(0.252763,0,0,0.765831,109.104,8.98517)"
+     style="font-size:12;"
+     id="g386">
+    <rect
+       width="285.502"
+       height="118.523"
+       x="16.6979"
+       y="99.2053"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect387" />
+    <rect
+       width="285.502"
+       height="118.523"
+       x="13.4238"
+       y="95.9309"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect388" />
+  </g>
+  <g
+     transform="matrix(0.297394,0,0,0.572692,101.502,21.6359)"
+     style="font-size:12;"
+     id="g364">
+    <rect
+       width="199.065"
+       height="61.5532"
+       x="61.8805"
+       y="68.4288"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect365" />
+    <rect
+       width="199.065"
+       height="61.5532"
+       x="59.2613"
+       y="65.8095"
+       style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect366" />
+  </g>
+  <text
+     x="202.746506"
+     y="102.992203"
+     transform="scale(0.73778,0.73778)"
+     style="font-size:14;font-weight:normal;stroke-width:1pt;font-family:Helvetica;text-anchor:middle;"
+     id="text367">
+    <tspan
+       x="202.746948"
+       y="102.992249"
+       id="tspan423">
+Persistent</tspan>
+    <tspan
+       x="202.746948"
+       y="116.992355"
+       id="tspan425">
+Objects</tspan>
+  </text>
+  <text
+     x="174.458496"
+     y="180.080795"
+     transform="scale(0.73778,0.73778)"
+     style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text389">
+    <tspan
+       x="174.458618"
+       y="180.080338"
+       id="tspan392">
+Session</tspan>
+  </text>
+  <g
+     transform="matrix(0.127369,0,0,0.765831,188.675,8.98517)"
+     style="font-size:12;"
+     id="g394">
+    <rect
+       width="285.502"
+       height="118.523"
+       x="16.6979"
+       y="99.2053"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect395" />
+    <rect
+       width="285.502"
+       height="118.523"
+       x="13.4238"
+       y="95.9309"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect396" />
+  </g>
+  <text
+     x="260.413269"
+     y="179.154739"
+     transform="scale(0.73778,0.73778)"
+     style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text397">
+    <tspan
+       x="260.412964"
+       y="179.154343"
+       id="tspan400">
+JDBC</tspan>
+  </text>
+  <g
+     transform="matrix(0.127369,0,0,0.765831,229.156,8.98517)"
+     style="font-size:12;"
+     id="g405">
+    <rect
+       width="285.502"
+       height="118.523"
+       x="16.6979"
+       y="99.2053"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect406" />
+    <rect
+       width="285.502"
+       height="118.523"
+       x="13.4238"
+       y="95.9309"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect407" />
+  </g>
+  <text
+     x="320.606903"
+     y="179.154739"
+     transform="scale(0.73778,0.73778)"
+     style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text408">
+    <tspan
+       x="320.606964"
+       y="179.154343"
+       id="tspan417">
+JNDI</tspan>
+  </text>
+  <g
+     transform="matrix(0.127369,0,0,0.765831,269.281,8.98517)"
+     style="font-size:12;"
+     id="g411">
+    <rect
+       width="285.502"
+       height="118.523"
+       x="16.6979"
+       y="99.2053"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect412" />
+    <rect
+       width="285.502"
+       height="118.523"
+       x="13.4238"
+       y="95.9309"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect413" />
+  </g>
+  <text
+     x="377.096313"
+     y="179.154739"
+     transform="scale(0.73778,0.73778)"
+     style="font-size:16;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text414">
+    <tspan
+       x="377.096008"
+       y="179.154999"
+       id="tspan145">
+JTA</tspan>
+  </text>
+</svg>

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/overview.png (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/overview.png)
===================================================================
(Binary files differ)

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/images/overview.svg (from rev 14074, core/trunk/documentation/manual/fr-FR/src/main/docbook/images/overview.svg)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/images/overview.svg	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/images/overview.svg	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,250 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
+[
+ <!ATTLIST svg
+  xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
+]>
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   width="248.031"
+   height="248.031"
+   id="svg1">
+  <defs
+     id="defs3">
+    <linearGradient
+       x1="0"
+       y1="0"
+       x2="1"
+       y2="0"
+       id="linearGradient127"
+       gradientUnits="objectBoundingBox"
+       spreadMethod="pad">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop128" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="1"
+         id="stop129" />
+    </linearGradient>
+    <linearGradient
+       x1="0"
+       y1="0"
+       x2="1"
+       y2="0"
+       id="linearGradient130"
+       xlink:href="#linearGradient127"
+       gradientUnits="objectBoundingBox"
+       spreadMethod="pad" />
+    <radialGradient
+       cx="0.5"
+       cy="0.5"
+       fx="0.5"
+       fy="0.5"
+       r="0.5"
+       id="radialGradient131"
+       xlink:href="#linearGradient127"
+       gradientUnits="objectBoundingBox"
+       spreadMethod="pad" />
+  </defs>
+  <g
+     transform="matrix(0.771934,0,0,0.771934,4.36019,-3.02123)"
+     style="font-size:12;"
+     id="g158">
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="16.6979"
+       y="17.3527"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect136" />
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="14.7335"
+       y="15.3883"
+       transform="translate(-1.30962,-1.30992)"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect126" />
+  </g>
+  <g
+     transform="matrix(0.771934,0,0,0.771934,4.36019,3.04452)"
+     style="font-size:12;"
+     id="g161">
+    <rect
+       width="285.502"
+       height="118.523"
+       x="16.6979"
+       y="99.2053"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect137" />
+    <rect
+       width="285.502"
+       height="118.523"
+       x="13.4238"
+       y="95.9309"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect132" />
+  </g>
+  <g
+     transform="matrix(0.771934,0,0,0.771934,4.36019,8.0993)"
+     style="font-size:12;"
+     id="g164">
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="16.6979"
+       y="222.966"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect138" />
+    <rect
+       width="285.502"
+       height="77.2688"
+       x="14.7335"
+       y="221.002"
+       transform="translate(-1.30962,-1.30992)"
+       style="fill:#d2d2d2;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect133" />
+  </g>
+  <g
+     transform="matrix(0.771934,0,0,0.543505,2.59104,21.1103)"
+     style="font-size:12;"
+     id="g167">
+    <rect
+       width="199.065"
+       height="61.5532"
+       x="61.8805"
+       y="68.4288"
+       style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect134" />
+    <rect
+       width="199.065"
+       height="61.5532"
+       x="59.2613"
+       y="65.8095"
+       style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+       id="rect135" />
+  </g>
+  <text
+     x="105.392174"
+     y="56.568123"
+     transform="scale(0.771934,0.771934)"
+     style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text183">
+    <tspan
+       x="105.392273"
+       y="56.568146"
+       id="tspan186">
+Application</tspan>
+  </text>
+  <text
+     x="81.820183"
+     y="103.149330"
+     transform="scale(0.771934,0.771934)"
+     style="font-size:20;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text188">
+    <tspan
+       x="81.820213"
+       y="103.149727"
+       id="tspan206">
+Persistent Objects</tspan>
+  </text>
+  <text
+     x="111.548180"
+     y="278.927887"
+     transform="scale(0.771934,0.771934)"
+     style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text197">
+    <tspan
+       x="111.547874"
+       y="278.927551"
+       id="tspan200">
+Database</tspan>
+  </text>
+  <text
+     x="94.436180"
+     y="153.805740"
+     transform="scale(0.771934,0.771934)"
+     style="font-size:24;font-weight:normal;stroke-width:1pt;font-family:Helvetica;"
+     id="text216">
+    <tspan
+       x="94.436180"
+       y="153.805740"
+       id="tspan221">
+HIBERNATE</tspan>
+  </text>
+  <g
+     transform="matrix(0.771934,0,0,0.771934,2.59083,1.02261)"
+     style="font-size:12;"
+     id="g254">
+    <g
+       transform="translate(4.58374,2.61928)"
+       id="g176">
+      <g
+         transform="matrix(0.571429,0,0,0.67347,-10.6174,117.093)"
+         id="g170">
+        <rect
+           width="199.065"
+           height="61.5532"
+           x="61.8805"
+           y="68.4288"
+           style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+           id="rect171" />
+        <rect
+           width="199.065"
+           height="61.5532"
+           x="59.2613"
+           y="65.8095"
+           style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+           id="rect172" />
+      </g>
+      <g
+         transform="matrix(0.571429,0,0,0.67347,138.682,117.093)"
+         id="g173">
+        <rect
+           width="199.065"
+           height="61.5532"
+           x="61.8805"
+           y="68.4288"
+           style="fill:#757575;fill-rule:evenodd;stroke-width:1pt;"
+           id="rect174" />
+        <rect
+           width="199.065"
+           height="61.5532"
+           x="59.2613"
+           y="65.8095"
+           style="fill:#e0e0e0;fill-rule:evenodd;stroke-width:1pt;"
+           id="rect175" />
+      </g>
+    </g>
+    <text
+       x="47.259438"
+       y="182.367538"
+       style="font-weight:bold;stroke-width:1pt;font-family:Courier;"
+       id="text191">
+      <tspan
+         x="47.259399"
+         y="182.367996"
+         id="tspan212">
+hibernate.</tspan>
+      <tspan
+         x="47.259399"
+         y="194.367996"
+         id="tspan214">
+properties</tspan>
+    </text>
+    <text
+       x="198.523010"
+       y="188.260941"
+       style="font-weight:normal;stroke-width:1pt;font-family:helvetica;"
+       id="text194">
+      <tspan
+         id="tspan195">
+XML Mapping</tspan>
+    </text>
+  </g>
+</svg>

Copied: core/trunk/documentation/manual/es-ES/src/main/docbook/legal_notice.xml (from rev 14073, core/trunk/documentation/manual/en-US/src/main/docbook/legal_notice.xml)
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/legal_notice.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/legal_notice.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,52 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<!--
+  ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+  ~
+  ~ 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
+  ~ Lesser General Public License, v. 2.1. This program is distributed in the
+  ~ hope that it will be useful, but WITHOUT A WARRANTY; without even the implied
+  ~ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  ~ Lesser General Public License for more details. You should have received a
+  ~ copy of the GNU Lesser General Public License, v.2.1 along with this
+  ~ distribution; if not, write to the Free Software Foundation, Inc.,
+  ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  ~
+  ~ Red Hat Author(s): Steve Ebersole
+  -->
+<legalnotice id="Legal_Notice">
+    <title>Legal Notice</title>
+    <para>
+        <address>
+            <street>1801 Varsity Drive</street>
+            <city>Raleigh</city>, <state>NC</state><postcode>27606-2072</postcode><country>USA</country>
+            <phone>Phone: +1 919 754 3700</phone>
+            <phone>Phone: 888 733 4281</phone>
+            <fax>Fax: +1 919 754 3701</fax>
+            <pob>PO Box 13588</pob><city>Research Triangle Park</city>, <state>NC</state><postcode>27709</postcode><country>USA</country>
+        </address>
+    </para>
+    <para>
+        Copyright <trademark class="copyright"></trademark> 2007 by Red Hat, Inc. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, V1.0 or later (the latest version is presently available at <ulink url="http://www.opencontent.org/openpub/">http://www.opencontent.org/openpub/</ulink>).
+    </para>
+    <para>
+        Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder.
+    </para>
+    <para>
+        Distribution of the work or derivative of the work in any standard (paper) book form for commercial purposes is prohibited unless prior permission is obtained from the copyright holder.
+    </para>
+    <para>
+        Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of Red Hat, Inc. in the United States and other countries.
+    </para>
+    <para>
+    All other trademarks referenced herein are the property of their respective owners.
+    </para>
+    <para>
+        The GPG fingerprint of the security at redhat.com key is:
+    </para>
+    <para>
+        CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E
+    </para>
+</legalnotice>
\ No newline at end of file

Added: core/trunk/documentation/manual/es-ES/src/main/docbook/legal_notice2.xml
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/legal_notice2.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/legal_notice2.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,16 @@
+<?xml version='1.0'?>
+<!DOCTYPE legalnotice PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<legalnotice id="Legal_Notice">
+    <title>Translation-specific Legal Notice</title>
+    <para>
+        Advertencia! Esta es una versi&#x00f3;n traducida del ingl&#x00e9;s de
+        la documentaci&#x00e9;n de referencia de Hibernate. La versi&#x00f3;n
+        traducida puede no estar actualizada! Sin embargo, las diferencias
+        deber&#x00ed;an ser s&#x00f3;lo menores. Consulta la documentaci&#x00f3;n
+        de referencia en ingl&#x00e9;s si est&#x00e1;s perdiendo informaci&#x00f3;n
+        o encuentras alg&#x00fa;n error de traducci&#x00f3;n. Si quieres colaborar con
+        una traducci&#x00f3;n en particular, cont&#x00e1;ctanos en la lista de correo
+        de desarrolladores de Hibernate.
+    </para>
+</legalnotice>
\ No newline at end of file

Deleted: core/trunk/documentation/manual/es-ES/src/main/docbook/master.xml
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/master.xml	2007-10-09 18:28:36 UTC (rev 14074)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/master.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -1,203 +0,0 @@
-<?xml version='1.0' encoding="iso-8859-1"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN"
-                      "../support/docbook-dtd/docbookx.dtd"
-[
-<!ENTITY quickstart             SYSTEM "modules/quickstart.xml">
-<!ENTITY tutorial               SYSTEM "modules/tutorial.xml">
-<!ENTITY architecture           SYSTEM "modules/architecture.xml">
-<!ENTITY configuration          SYSTEM "modules/configuration.xml">
-<!ENTITY persistent-classes     SYSTEM "modules/persistent_classes.xml">
-<!ENTITY basic-mapping          SYSTEM "modules/basic_mapping.xml">
-<!ENTITY collection-mapping     SYSTEM "modules/collection_mapping.xml">
-<!ENTITY association-mapping    SYSTEM "modules/association_mapping.xml">
-<!ENTITY component-mapping      SYSTEM "modules/component_mapping.xml">
-<!ENTITY inheritance-mapping    SYSTEM "modules/inheritance_mapping.xml">
-<!ENTITY session-api            SYSTEM "modules/session_api.xml">
-<!ENTITY transactions           SYSTEM "modules/transactions.xml">
-<!ENTITY events                 SYSTEM "modules/events.xml">
-<!ENTITY batch                  SYSTEM "modules/batch.xml">
-<!ENTITY query-hql              SYSTEM "modules/query_hql.xml">
-<!ENTITY query-criteria         SYSTEM "modules/query_criteria.xml">
-<!ENTITY query-sql              SYSTEM "modules/query_sql.xml">
-<!ENTITY filters                SYSTEM "modules/filters.xml">
-<!ENTITY xml                    SYSTEM "modules/xml.xml">
-<!ENTITY performance            SYSTEM "modules/performance.xml">
-<!ENTITY toolset-guide          SYSTEM "modules/toolset_guide.xml">
-<!ENTITY example-parentchild    SYSTEM "modules/example_parentchild.xml">
-<!ENTITY example-weblog         SYSTEM "modules/example_weblog.xml">
-<!ENTITY example-mappings       SYSTEM "modules/example_mappings.xml">
-<!ENTITY best-practices         SYSTEM "modules/best_practices.xml">
-]>
-
-<book lang="es">
-
-    <bookinfo>
-        <title>HIBERNATE - Persistencia Relacional para Java Idiom&#x00e1;tico</title>
-        <subtitle>Documentaci&#x00f3;n de Referencia de Hibernate</subtitle>
-        <releaseinfo>3.0.5</releaseinfo>
-    </bookinfo>
-
-    <toc/>
-
-    <preface id="preface" revision="2">
-        <title>Prefacio</title>
-
-        <para>
-            Advertencia! Esta es una versi&#x00f3;n traducida del ingl&#x00e9;s de
-            la documentaci&#x00e9;n de referencia de Hibernate. La versi&#x00f3;n 
-            traducida puede no estar actualizada! Sin embargo, las diferencias
-            deber&#x00ed;an ser s&#x00f3;lo menores. Consulta la documentaci&#x00f3;n
-            de referencia en ingl&#x00e9;s si est&#x00e1;s perdiendo informaci&#x00f3;n
-            o encuentras alg&#x00fa;n error de traducci&#x00f3;n. Si quieres colaborar con
-            una traducci&#x00f3;n en particular, cont&#x00e1;ctanos en la lista de correo
-            de desarrolladores de Hibernate.
-        </para>
-
-        <para>
-            Traductor(es): Bernardo Antonio Buffa Colom&#x00e9; &lt;kreimer at bbs.frc.utn.edu.ar&gt;
-<!--,
-            Antonio L&#x00f3;pez Gota &lt;antoniogota at gmail.com&gt; -->
-        </para>
-
-        <para>
-            Trabajar con software orientado a objetos y una base de datos relacional puede ser
-            inc&#x00f3;modo y consumir tiempo en los entornos de empresa de hoy. Hibernate es una
-            herramienta de mapeo objeto/relacional para entornos Java. El t&#x00e9;rmino mapeo
-            objeto/relacional (MOR) hace referencia a la t&#x00e9;cnica de mapear una
-            representaci&#x00f3;n de datos desde un modelo de objetos a un modelo de datos relacional
-            con un esquema basado en SQL.
-        </para>
-
-        <para>
-            Hibernate no s&#x00f3;lo se encarga de mapear de clases Java a tablas de base de datos
-            (y de tipos de datos de Java a tipos de datos SQL), sino que tambi&#x00e9;n provee
-            facilidades de consulta y recuperaci&#x00f3;n de datos y puede reducir significativamente
-            el tiempo de desarrollo que de otra forma se gasta en el manejo de los datos en SQL y JDBC.
-        </para>
-
-        <para>
-            La meta de Hibernate es relevar al desarrollador del 95 por ciento de las tareas comunes
-            relacionadas a la programaci&#x00f3;n de la persistencia de los datos.
-            Hibernate puede no ser la mejor soluci&#x00f3;n para aplicaciones que usan solamente
-            procedimientos almacenados para implementar la l&#x00f3;gica de negocio en la base de
-            datos, es mas &#x00fa;til con modelos de dominio orientados a objetos y l&#x00f3;gica de
-            negocio en middle-tier basada en Java. Sin embargo, Hibernate ciertamente puede ayudarte
-            a quitar o encapsular c&#x00f3;digo SQL espec&#x00ed;fico de vendedor y ayudar&#x00e1;
-            con la tarea com&#x00fa;n de traducci&#x00f3;n de resultados desde una representaci&#x00f3;n
-            tabular a un grafo de objetos.
-        </para>
-
-        <para>
-            Si eres nuevo en Hibernate y lo del Mapeo Objeto/Relacional o incluso en Java,
-            sigue por favor estos pasos:
-        </para>
-
-        <orderedlist>
-            <listitem>
-                <para>
-                    Lee <xref linkend="quickstart"/> para un tutorial de 30 minutos, usando Tomcat.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    Lee <xref linkend="architecture"/> para entender los entornos en los que
-                    puede ser usado Hibernate.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    Dale una mirada al directorio <literal>eg/</literal> en la distribuci&#x00f3;n
-                    de Hibernate, contiene una aplicaci&#x00f3;n independiente simple.
-                    Copia tu driver JDBC al directorio <literal>lib/</literal> y edita 
-                    <literal>etc/hibernate.properties</literal>, especificando los valores 
-                    correctos para tu base de datos. Desde l&#x00ed;nea de comandos en el
-                    directorio de la distribuci&#x00f3;n, tipea <literal>ant eg</literal>
-                    (usando Ant), o bajo Windows, tipea <literal>build eg</literal>.
-                </para>
-            </listitem>
-            <listitem>
-                <para>
-                    Usa esta documentaci&#x00f3;n de referencia como tu fuente de informaci&#x00f3;n
-                    primaria. Ten en consideraci&#x00f3;n leer <emphasis>Java Persistence with Hibernate</emphasis>
-                    (http://www.manning.com/bauer2) si necesitas mas ayuda con el dise&#x00f1;o
-                    de aplicaciones o si prefieres un tutorial paso a paso.
-                    Visita tambi&#x00e9;n http://caveatemptor.hibernate.org y descarga la aplicaci&#x00f3;n
-                    de ejemplo para Java Persistence with Hibernate.
-                </para>
-            </listitem>
-            <listitem>
-				<para>
-					Los FAQs son respondidos en el sitio web de Hibernate.
-				</para>
-            </listitem>
-			<listitem>
-				<para>
-                                        En el sitio web de Hibernate hay enlaces a demos de terceros, ejemplos
-                                        y tutoriales.
-				</para>
-			</listitem>
-            <listitem>
-                <para>
-                    El Area de Comunidad en el sitio web de Hibernate es una buena fuente
-                    de patrones de dise&#x00f1;o y varias soluciones de integraci&#x00f3;n
-                    (Tomcat, JBoss, Struts, EJB, etc.).
-                </para>
-            </listitem>
-         </orderedlist>
-
-         <para>
-             Si tienes preguntas, usa el foro de usuarios enlazado en el sitio web de Hibernate.
-             Tambi&#x00e9;n proveemos un sistema de seguimiento JIRA para reportes de defectos y
-             peticiones de nuevas caracter&#x00ed;sticas.
-             Si estas interesado en el desarrollo de Hibernate, &#x00fa;nete a la lista de correo
-             de desarrolladores. Si estas interesado en traducir esta documentaci&#x00f3;n a tu
-             lenguaje, cont&#x00e1;ctanos en la lista de correo de desarrolladores.
-         </para>
-
-         <para>
-             A trav&#x00e9;s de JBoss Inc. (see http://www.hibernate.org/SupportTraining/) hay
-             disponibilidad de soporte comercial de desarrollo, soporte de producci&#x00f3;n y
-             entrenamiento en Hibernate.
-             Hibernate es un proyecto de la suite de productos de c&#x00f3;digo abierto
-             JBoss Professional.
-         </para>
-
-    </preface>
-
-    &quickstart;
-    &tutorial;
-    &architecture;
-
-    &configuration;
-
-    &persistent-classes;
-
-    &basic-mapping;
-    &collection-mapping;
-    &association-mapping;
-    &component-mapping;
-    &inheritance-mapping;
-
-    &session-api;
-    &transactions;
-    &events;
-    &batch;
-
-    &query-hql;
-    &query-criteria;
-    &query-sql;
-    &filters;
-    &xml;
-
-    &performance;
-
-    &toolset-guide;
-
-    &example-parentchild;
-    &example-weblog;
-    &example-mappings;
-
-    &best-practices;
-
-</book>
-

Added: core/trunk/documentation/manual/es-ES/src/main/docbook/translators.xml
===================================================================
--- core/trunk/documentation/manual/es-ES/src/main/docbook/translators.xml	                        (rev 0)
+++ core/trunk/documentation/manual/es-ES/src/main/docbook/translators.xml	2007-10-09 18:45:36 UTC (rev 14075)
@@ -0,0 +1,10 @@
+<?xml version='1.0'?>
+
+<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<authorgroup id="AuthorGroup">
+    <othercredit class="translator">
+        <othername><![CDATA[Bernardo Antonio Buffa Colom&#x00e9]]></othername>
+        <email>kreimer at bbs.frc.utn.edu.ar</email>
+    </othercredit>
+</authorgroup>
\ No newline at end of file




More information about the hibernate-commits mailing list