2005-06-13 08:04:11 -04:00
|
|
|
<chapter id="session-configuration" revision="1">
|
|
|
|
|
|
|
|
<title>Configuración</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Debido a que Hibernate está diseñado para operar en muchos entornos
|
|
|
|
diferentes, hay un gran número de parámetros de configuración.
|
|
|
|
Afortunadamente, la mayorí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ólo pon el
|
|
|
|
fichero de ejemplo en tu classpath y personalízalo.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<sect1 id="configuration-programmatic" revision="1">
|
|
|
|
<title>Configuración programá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ó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ándola
|
|
|
|
directamente y especificando documentos de mapeo XML. Si los ficheros de mapeo
|
|
|
|
está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á 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ódigo.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Una <literal>Configuration</literal> también te permite especificar
|
|
|
|
propiedades de configuració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 única forma de pasar propiedades de configuració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í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><property></literal>
|
|
|
|
en <literal>hibernate.cfg.xml</literal> (discutido luego).
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</orderedlist>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
<literal>hibernate.properties</literal> es el enfoque más fácil
|
|
|
|
si quieres comenzar rápido.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
La <literal>Configuration</literal> está 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ón debe obtener una fábrica de instancias de <literal>Session</literal>.
|
|
|
|
Esta fábrica está concebida para ser compartida por todas las hebras de
|
|
|
|
aplicación:
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<programlisting><![CDATA[SessionFactory sessions = cfg.buildSessionFactory();]]></programlisting>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Hibernate permite que tu aplicación instancie más de una
|
|
|
|
<literal>SessionFactory</literal>. Esto es útil si estás usando
|
|
|
|
má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á una
|
|
|
|
conexión JDBC del pool.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Para que esto funcione, necesitamos pasar algunas propiedades de conexión
|
|
|
|
JDBC a Hibernate. Todos los nombres de propiedades y su semántica
|
|
|
|
están definidas en la clase <literal>org.hibernate.cfg.Environment</literal>.
|
|
|
|
Describiremos ahora las configuraciones más importantes para la conexión
|
|
|
|
JDBC.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Hibernate obtendrá (y tendrá 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ó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ña del usuario de base de datos</emphasis>
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry>
|
|
|
|
<literal>hibernate.connection.pool_size</literal>
|
|
|
|
</entry>
|
|
|
|
<entry>
|
|
|
|
<emphasis>número má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á concebido para ayudarte a comenzar y
|
|
|
|
<emphasis>no está concebido para usar en un sistema de producción</emphasis>
|
|
|
|
ni siquiera para pruebas de rendimiento. Debes usar un pool de terceros para
|
|
|
|
un mejor rendimiento y estabilidad. Sólo remplaza la propiedad
|
|
|
|
<literal>hibernate.connection.pool_size</literal> con configuraciones
|
|
|
|
específicas del pool de conexiones. Esto desactivará el pool
|
|
|
|
interno de Hibernate. Por ejemplo, podrías querer usar C3P0.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
C3P0 es un pool de conexiones JDBC de código abierto distribuido
|
|
|
|
junto a Hibernate en el directorio <literal>lib</literal>.
|
|
|
|
Hibernate usará su <literal>C3P0ConnectionProvider</literal>
|
|
|
|
para pooling de conexiones si estableces propiedades <literal>hibernate.c3p0.*</literal>.
|
|
|
|
Si quieres usar Proxool refiérete al <literal>hibernate.properties</literal>
|
|
|
|
empaquetado y al sitio web de Hibernate para más información.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Aquí 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á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ó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ña del usuario de base de datos</emphasis> (opcional)
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
</tbody>
|
|
|
|
</tgroup>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
He aquí 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án automáticamente
|
|
|
|
en las transacciones del servidor de aplicaciones manejadas por contenedor.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Pueden darse propiedades de conexió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ón personalizada estableciendo
|
|
|
|
<literal>hibernate.connection.provider_class</literal>.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="configuration-optional" revision="1">
|
|
|
|
<title>Parámetros de configuración opcionales</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Hay un número de otras propiedades que controlan el comportamiento
|
|
|
|
de Hibernate en tiempo de ejecució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ó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écnicas arriba descritas.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<table frame="topbot" id="configuration-optional-properties" revision="8">
|
|
|
|
<title>Propiedades de Configuració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ó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á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á
|
|
|
|
ligada a este nombre en JNDI automáticamente
|
|
|
|
despué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áxima del
|
|
|
|
árbol de recuperación por outer join
|
|
|
|
para asociaciones de un extremo solo (uno-a-uno, muchos-a-uno).
|
|
|
|
Un <literal>0</literal> deshabilita la recuperació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ño por defecto para la recuperació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ó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á en menos bloqueos muertos de transacció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á estadísticas
|
|
|
|
útiles para la afinació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á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á comentarios dentro del SQL,
|
|
|
|
para una más fácil depuració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ósito</entry>
|
|
|
|
</row>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<row>
|
|
|
|
<entry>
|
|
|
|
<literal>hibernate.jdbc.fetch_size</literal>
|
|
|
|
</entry>
|
|
|
|
<entry>
|
|
|
|
Un valor distinto de cero que determina el tamaño
|
|
|
|
de recuperació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ón). Hibernate usará
|
|
|
|
DML en lote para versionar automá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ía de las aplicaciones no necesitarán
|
|
|
|
esta propiedad de configuración.
|
|
|
|
<para>
|
|
|
|
<emphasis role="strong">ej.</emphasis>
|
|
|
|
<literal>classname.of.Batcher</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ólo es necesaria cuando se usan conexiones
|
|
|
|
JDBC provistas por el usuario, en caso contrario Hibernate usa los
|
|
|
|
metadatos de conexió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és de insertar.
|
|
|
|
Requiere un driver JDBC3+ y un JRE1.4+. Establé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ó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ón JDBC.
|
|
|
|
Comprueba <literal>java.sql.Connection</literal> para valores
|
|
|
|
significativos pero observa que la mayorí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á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ándo Hibernate debe liberar las conexiones JDBC.
|
|
|
|
Por defecto, una conexión JDBC es retenida hasta que la sesión
|
|
|
|
es cerrada explícitamente o desconectada. Para un datasource JTA
|
|
|
|
del servidor de aplicaciones, debes usar <literal>after_statement</literal>
|
|
|
|
para liberar agresivamente las conexiones después de cada llamada
|
|
|
|
JDBC. Para una conexión no JTA, frecuentemente tiene sentido liberar
|
|
|
|
la conexión al final de cada transacción, usando
|
|
|
|
<literal>after_transaction</literal>. <literal>auto</literal> eligirá
|
|
|
|
<literal>after_statement</literal> para las estrategias JTA o CMT
|
|
|
|
de transacción y <literal>after_transaction</literal> para la
|
|
|
|
estrategia JDBC de transacció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><propertyName></emphasis></literal>
|
|
|
|
</entry>
|
|
|
|
<entry>
|
|
|
|
Pasa la propiedad JDBC <literal>propertyName</literal>
|
|
|
|
a <literal>DriverManager.getConnection()</literal>.
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry>
|
|
|
|
<literal>hibernate.jndi.<emphasis><propertyName></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é 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ó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ón del caché de segundo nivel
|
|
|
|
para minimizar escrituras, al costo de lecturas más frecuentes.
|
|
|
|
Esto es más útil para cachés en cluster y,
|
|
|
|
en Hibernate3, está habilitado por defecto para implementaciones
|
|
|
|
de caché 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é de lectura, consultas individuales todaví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é
|
|
|
|
de segundo nivel, que está habilitado por defecto para clases
|
|
|
|
que especifican un mapeo <literal><cache></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ón
|
|
|
|
del caché 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é
|
|
|
|
de segundo nivel en un formato má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ó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ó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é a nivel de JVM está
|
|
|
|
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ón se limpiará (flushed)
|
|
|
|
automáticamente durante la fase previa a la compleción
|
|
|
|
de la transacción. (Muy ú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ón será cerrada automáticamente
|
|
|
|
durante la fase posterior a la compleción de la transacción.
|
|
|
|
(Muy ú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áneas</title>
|
|
|
|
<tgroup cols="2">
|
|
|
|
<colspec colname="c1" colwidth="1*"/>
|
|
|
|
<colspec colname="c2" colwidth="1*"/>
|
|
|
|
<thead>
|
|
|
|
<row>
|
|
|
|
<entry>Nombre de propiedad</entry>
|
|
|
|
<entry>Propósito</entry>
|
|
|
|
</row>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<row>
|
|
|
|
<entry>
|
|
|
|
<literal>hibernate.query.factory_class</literal>
|
|
|
|
</entry>
|
|
|
|
<entry>
|
|
|
|
Elige la implementació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ímbolos en consultas Hibernate a
|
|
|
|
símbolos SQL. (los símbolos puedem ser
|
|
|
|
nombres de funció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áticamente DDL de esquema cuando
|
|
|
|
al crear la <literal>SessionFactory</literal>.
|
|
|
|
Con <literal>create-drop</literal>, el esquema de
|
|
|
|
base de datos será desechado cuando la
|
|
|
|
<literal>SessionFactory</literal> se cierre explí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ón en tiempo de
|
|
|
|
ejecución (propiedad a nivel de sistema). La reflección
|
|
|
|
a veces puede ser útil ante la aparició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ó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ón por Unión Externa (Outer Join Fetching)</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Si tu base de datos soporta uniones externas del estilo ANSI, Oracle o Sybase, la
|
|
|
|
<emphasis>recuperación por unión externa</emphasis> aumentará
|
|
|
|
frecuentemente el rendimiento limitando el número de llamadas a la base de datos
|
|
|
|
(al costo de más trabajo posiblemente realizado por la base de datos misma).
|
|
|
|
La recuperación por unió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ído en una sola <literal>SELECT</literal> SQL.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
La recuperación por unió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ón
|
|
|
|
por unió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ás información.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2 id="configuration-optional-binarystreams" revision="1">
|
|
|
|
<title>Flujos Binarios</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Oracle limita el tamañ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é de segundo nivel y de lectura</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Las propiedades prefijadas por <literal>hibernate.cache</literal>
|
|
|
|
te permiten usar un sistema de caché de segundo nivel
|
|
|
|
en el ámbito de un proceso o cluster con Hibernate.
|
|
|
|
Ver <xref linkend="performance-cache"/> para más detalles.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2 id="configuration-optional-querysubstitution">
|
|
|
|
<title>Sustitución de Lenguaje de Consulta</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Puedes definir nuevos sí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ía que los sí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ía renombrar la funció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á un número de métricas que son útiles
|
|
|
|
al afinar un sistema en ejecución vía
|
|
|
|
<literal>SessionFactory.getStatistics()</literal>. Hibernate puede incluso ser
|
|
|
|
configurado para exponer estas estadísticas vía JMX. Lee el
|
|
|
|
Javadoc de las interfaces en <literal>org.hibernate.stats</literal>
|
|
|
|
para más informació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á 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á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ón de problemas. Las categorías de registro
|
|
|
|
más interesantes son las siguientes:
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<table frame="topbot" id="log-categories" revision="2">
|
|
|
|
<title>Categorías de Registro de Hibernate</title>
|
|
|
|
<tgroup cols="2">
|
|
|
|
<colspec colwidth="1*"/>
|
|
|
|
<colspec colwidth="2.5*"/>
|
|
|
|
<thead>
|
|
|
|
<row>
|
|
|
|
<entry>Categoría</entry>
|
|
|
|
<entry>Funció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á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áximo
|
|
|
|
de 20 entidades) asociadas con la sesión en tiempo
|
|
|
|
de limpieza (flush)
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><literal>org.hibernate.cache</literal></entry>
|
|
|
|
<entry>Registra toda la actividad del caché de segundo nivel</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><literal>org.hibernate.transaction</literal></entry>
|
|
|
|
<entry>Registra la actividad relacionada con la transacción</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><literal>org.hibernate.jdbc</literal></entry>
|
|
|
|
<entry>Registra toda adquisición de recursos JDBC</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><literal>org.hibernate.hql.ast</literal></entry>
|
|
|
|
<entry>Regista los ASTs de HQL y SQL, así como
|
|
|
|
otra información sobre análisis de consultas.</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><literal>org.hibernate.secure</literal></entry>
|
|
|
|
<entry>Registra todas las peticiones de autorización JAAS</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><literal>org.hibernate</literal></entry>
|
|
|
|
<entry>
|
|
|
|
Registra todo (mucha información, pero muy útil
|
|
|
|
para la resolució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í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ándar de nombrado" para objetos de la base de datos
|
|
|
|
y elementos de esquema.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Puedes proveer reglas para generar automáticamente identificadores de
|
|
|
|
base de datos a partir de identificadores JDBC o para procesar nombres
|
|
|
|
"lógicos" de columnas y tablas dados en el fichero de mapeo en nombres
|
|
|
|
"fí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í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 útil para algunas aplicaciones.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="configuration-xmlconfig" revision="2">
|
|
|
|
<title>Fichero de configuración XML</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Un enfoque alternativo de configuración es especificar una
|
|
|
|
configuració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án presentes, para sobrescribir propiedades.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
El fichero de configuración XML se espera por defecto en la
|
|
|
|
raíz o tu <literal>CLASSPATH</literal>. He aquí 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"/>
|
2005-06-19 12:50:03 -04:00
|
|
|
<collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
|
2005-06-13 08:04:11 -04:00
|
|
|
|
|
|
|
</session-factory>
|
|
|
|
|
|
|
|
</hibernate-configuration>]]></programlisting>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Como puedes ver, la ventaja de este enfoque es la externalización de los
|
|
|
|
nombres de los fichero de mapeo a configuración. El
|
|
|
|
<literal>hibernate.cfg.xml</literal> es también más conveniente
|
|
|
|
una vez que hayas afinado el caché de Hibernate. Observa que elecció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ó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ó con Servidores de Aplicaciones J2EE</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Hibernate tiene los siguientes puntos de integració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é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ídas a través de varios
|
|
|
|
datasources. Puedes también, por supuesto, demarcar los límites
|
|
|
|
de las transacciones programáticamente (BMT) o podrías querer usar
|
|
|
|
para esto la API opcional de <literal>Transaction</literal> de Hibernate para
|
|
|
|
mantener tu código portable.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
<emphasis>Ligamento Automático JNDI</emphasis>: Hibernate puede ligar sus
|
|
|
|
<literal>SessionFactory</literal> a JNDI después del arranque.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
<emphasis>Ligamento de Sesión JTA:</emphasis>
|
|
|
|
La <literal>Session</literal> de Hibernate puede ser ligada automáticamente
|
|
|
|
al ámbito de transacciones JTA si usas EJBs. Simplemente busca la
|
|
|
|
<literal>SessionFactory</literal> de JNDI y obtén la <literal>Session</literal>
|
|
|
|
actual. Deja que Hibernate cuide de limpiar y cerrar la <literal>Session</literal>
|
|
|
|
cuando se complete tu transacción JTA. La demarcación de transacció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ódigo de una línea de arranque para
|
|
|
|
construir tu <literal>SessionFactory</literal> desde una <literal>Configuration</literal>.
|
|
|
|
El contenedor arrancará tu <literal>HibernateService</literal>, e idealmente también
|
|
|
|
cuidará de las dependencias entre servicios (El datasource debe estar
|
|
|
|
disponible antes que arranque Hibernate, etc).
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Dependiendo de tu entorno, podrías tener que establecer la opción
|
|
|
|
de configuració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ón de la estrategia de transacción</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
La API de <literal>Session</literal> de Hibernate es independiente de cualquier
|
|
|
|
demarcación de transacción en tu arquitectura. Si dejas que Hibernate
|
|
|
|
use JDBC directamente, a travé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é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ó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ábrica para las instancias de <literal>Transaction</literal>
|
|
|
|
estableciendo la propiedad de configuración <literal>hibernate.transaction.factory_class</literal>
|
|
|
|
de Hibernate.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Hay tres elecciones está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ón
|
|
|
|
existente estó por debajo en este contexto (ej. método de un
|
|
|
|
bean de sesión EJB), en otro caso una nueva transacció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én tus propias estrategias de transacción
|
|
|
|
(para un servicio de transacción CORBA, por ejemplo).
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Algunas funcionalidades en Hibernate (ej, el caché de segundo nivel, ligamento
|
|
|
|
automá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ó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ón de la fábrica y la creación de nuevas
|
|
|
|
<literal>Session</literal>s. Observa que esto no está 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á ligada a JNDI (Esto es especialmente
|
|
|
|
útil en entornos con una implementació JNDI de sólo lectura por defecto,
|
|
|
|
ej. Tomcat.)
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Al ligar la <literal>SessionFactory</literal> a JNDI, Hibernate usará los valores de
|
|
|
|
<literal>hibernate.jndi.url</literal>, <literal>hibernate.jndi.class</literal> para instanciar
|
|
|
|
un contexto inicial. Si étos no se especifican, se usará el
|
|
|
|
<literal>InitialContext</literal> por defecto.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Hibernate colocará automáticamente la <literal>SessionFactory</literal>
|
|
|
|
en JNDI después que llames a <literal>cfg.buildSessionFactory()</literal>.
|
|
|
|
Esto significa que tendrás al menos esta llamada en algún código
|
|
|
|
de arranque (o clase de utilidad) en tu aplicació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úsqueda
|
|
|
|
JNDI. Observa que esta configuración no es necesaria si usas la clase de ayuda
|
|
|
|
<literal>HibernateUtil</literal> introducida en el capítulo uno, que actúa
|
|
|
|
como un registro Singleton. Sin embargo, <literal>HibernateUtil</literal> es más
|
|
|
|
común en un entorno no manejado.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2 id="configuration-j2ee-currentsession" revision="1">
|
|
|
|
<title>Ligado automático de JTA y Session</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Para entornos no manejados hemos sugerido <literal>HibernateUtil</literal> con una
|
|
|
|
<literal>SessionFactory</literal> estática, y administración de la
|
|
|
|
<literal>Session</literal> de Hibernate. Este enfoque no es fácil de usar
|
|
|
|
en un entorno EJB, al poder ejecutarse muchos EJBs dentro de la misma transacció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é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ón JTA actual, se arrancará y asignará una.
|
|
|
|
Ambas opciones de configuración <literal>hibernate.transaction.flush_before_completion</literal>
|
|
|
|
y <literal>hibernate.transaction.auto_close_session</literal>, serán establecidas
|
|
|
|
automáticamente para cada <literal>Session</literal> que obtengas con
|
|
|
|
<literal>getCurrentSession()</literal>, de modo que éstas serán
|
|
|
|
limpiadas (flushed) y cerradas automáticamente cuando el contenedor complete
|
|
|
|
las transacciones JTA.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Si tu, por ejemplo, usas el patrón de diseño DAO para escribir tu
|
|
|
|
capa de persistencia, todos los DAO's buscan la <literal>SessionFactory</literal>
|
|
|
|
cuando se necesite y abren la sesión "actual". No hay necesidad de pasar
|
|
|
|
las instancias de <literal>SessionFactory</literal> o <literal>Session</literal>
|
|
|
|
alrededor entre el código de control y el código DAO.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2 id="configuration-j2ee-jmx" revision="1">
|
|
|
|
<title>Despliegue JMX</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
La línea <literal>cfg.buildSessionFactory()</literal> todaví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ón reales son específicos del vendedor.
|
|
|
|
He aquí 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ón <literal>.sar</literal>
|
|
|
|
(fichero de servicio). También necesitas empaquetar Hibernate, sus bibliotecas
|
|
|
|
de terceros requeridas, tus clases persistentes compiladas, así como tus ficheros de mapeo
|
|
|
|
en el mismo fichero. Tus beans de empresa (usualmente beans de sesió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ón
|
|
|
|
de JBoss AS para más información sobre el servicio JMX y despliegue de EJB.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
</chapter>
|
|
|
|
|