Download - Hibernate 3
Capítulo 3. Configuración
3.1. Configuración programática
3.2. Obtención de una SessionFactory
3.3. Conexiones JDBC
3.4. Parámetros de configuración opcionales
3.4.1. Dialectos de SQL
3.4.2. Recuperación por Unión Externa - Outer Join Fetching
3.4.3. Flujos Binarios
3.4.4. Caché de segundo nivel y de lectura
3.4.5. Sustitución de Lenguaje de Consulta
3.4.6. Estadísticas de Hibernate
3.5. Registros de mensajes (Logging)
3.6. Implementación de una NamingStrategy
3.7. Archivo de configuración XML
3.8. Integración con Servidores de Aplicaciones J2EE
3.8.1. Configuración de la estrategia de transacción
3.8.2. SessionFactory enlazado a JNDI
3.8.3. Administración de contexto de Sesión Actual con JTA
3.8.4. Despliegue JMX
Hibernate está diseñado para operar en muchos entornos diferentes y por lo tanto hay un gran número de
parámetros de configuración. Afortunadamente, la mayoría tiene valores predeterminados sensibles y
Hibernate se distribuye con un archivo hibernate.properties de ejemplo en etc/ que muestra las diversas
opciones. Simplemente ponga el fichero de ejemplo en su ruta de clase y personalícelo de acuerdo a sus
necesidades.
3.1. Configuración programática
Una instancia de org.hibernate.cfg.Configuration representa un conjunto entero de mapeos de los tipos Java
de una aplicación a una base de datos SQL. La org.hibernate.cfg.Configuration se utiliza para construir
unaorg.hibernate.SessionFactory inmutable. Los mapeos se compilan desde varios archivos de mapeo XML.
Puede obtener una instancia de org.hibernate.cfg.Configuration instanciándola directamente y especificando
los documentos de mapeo XML. Si los archivos de mapeo están en la ruta de clase, utilice addResource().
Por ejemplo:
Configuration cfg = new Configuration()
.addResource("Item.hbm.xml")
.addResource("Bid.hbm.xml");
Una manera opcional es especificar la clase mapeada y dejar que Hibernate encuentre el documento de
mapeo por usted:
Configuration cfg = new Configuration()
.addClass(org.hibernate.auction.Item.class)
.addClass(org.hibernate.auction.Bid.class);
Luego Hibernate buscará los archivos de mapeo
llamados /org/hibernate/auction/Item.hbm.xml y/org/hibernate/auction/Bid.hbm.xml en la ruta de clase.
Este enfoque elimina cualquier nombre de archivo establecido manualmente.
Una org.hibernate.cfg.Configuration también le permite especificar las propiedades de configuración. Por
ejemplo:
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");
Esta no es la única manera de pasar propiedades de configuración a Hibernate. Algunas opciones incluyen:
1. Pasar una instancia de java.util.Properties a Configuration.setProperties().
2. Colocar un archivo llamado hibernate.properties en un directorio raíz de la ruta de clase.
3. Establecer propiedades System utilizando java -Dproperty=value.
4. Incluir los elementos <property> en hibernate.cfg.xml (esto se discute más adelante).
Si quiere empezar rápidamente hibernate.properties es el enfoque más fácil.
La org.hibernate.cfg.Configuration está concebida como un objeto de tiempo de inicio que se va a descartar
una vez se crea una SessionFactory.
3.2. Obtención de una SessionFactory
Cuando la org.hibernate.cfg.Configuration ha analizado sintácticamente todos los mapeos, la aplicación tiene
que obtener una fábrica para las instancias org.hibernate.Session. Esta fábrica está concebida para que todos
los hilos de la aplicación la compartan:
SessionFactory sessions = cfg.buildSessionFactory();
Hibernate permite que su aplicación instancie más de una org.hibernate.SessionFactory. Esto es útil si está
utilizando más de una base de datos.
3.3. Conexiones JDBC
Se aconseja que la org.hibernate.SessionFactory cree y almacene en pool conexiones JDBC por usted Si
adopta este enfoque, el abrir una org.hibernate.Session es tan simple como:
Session session = sessions.openSession(); // open a new Session
En el momento en que inicie una tarea que requiera acceso a la base de datos, se obtendrá una conexión
JDBC del pool.
Para que esto funcione, primero necesita pasar algunas las propiedades de conexión JDBC a Hibernate.
Todos los nombres de las propiedades de Hibernate y su semántica están definidas en la
claseorg.hibernate.cfg.Environment. Ahora describiremos las configuraciones más importantes para la
conexión JDBC.
Hibernate obtendrá y tendrá en pool las conexiones utilizando java.sql.DriverManager si configura las
siguientes propiedades:
Tabla 3.1. Propiedades JDBC de Hibernate
Nombre de la propiedad Propósito
hibernate.connection.driver_class JDBC driver class
hibernate.connection.url JDBC URL
hibernate.connection.username database user
hibernate.connection.password database user password
hibernate.connection.pool_size maximum number of pooled connections
Sin embargo, el algoritmo de pooling de la conexión propia de Hibernate es algo rudimentario. Está
concebido para ayudarle a comenzar y no para utilizarse en un sistema de producción ni siquiera para
pruebas de rendimiento. Para alcanzar un mejor rendimiento y estabilidad debe utilizar un pool de
terceros. Sólo remplace la propiedad hibernate.connection.pool_size con configuraciones específicas del
pool de conexiones. Esto desactivará el pool interno de Hibernate. Por ejemplo, es posible utilizar C3P0.
C3P0 es un pool de conexiones JDBC de código abierto distribuido junto con Hibernate en el directorio lib.
Hibernate utilizará su org.hibernate.connection.C3P0ConnectionProvider para pooling de conexiones si establece
propiedades hibernate.c3p0.*. Si quiere utilizar Proxool refiérase a hibernate.properties incluído en el paquete
y al sitio web de Hibernate para obtener más información.
Aquí hay un archivo hibernate.properties de ejemplo para c3p0:
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
Para su utilización dentro de un servidor de aplicaciones, casi siempre usted debe configurar Hibernate
para obtener conexiones de un javax.sql.Datasource del servidor de aplicaciones registrado en JNDI.
Necesitará establecer al menos una de las siguientes propiedades:
Tabla 3.2. Propiedades de la Fuente de Datos de Hibernate
Nombre de la propiedad Propósito
hibernate.connection.datasource datasource JNDI name
hibernate.jndi.url URL del proveedor JNDI (opcional)
hibernate.jndi.class clase del JNDI InitialContextFactory (opcional)
hibernate.connection.username usuario de la base de datos (opcional)
hibernate.connection.password contraseña del usuario de la base de datos (opcional)
He aquí un archivo hibernate.properties de ejemplo para una fuente de datos JNDI provisto por un servidor de
aplicaciones:
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
Las conexiones JDBC obtenidas de una fuente de datos JNDI participarán automáticamente en las
transacciones del servidor de aplicaciones administradas por el contenedor.
Pueden darse propiedades de conexión arbitrarias anteponiendo "hibernate.connnection" al nombre de
propiedad de la conexión. Por ejemplo, puede especificar una propiedad de
conexión charSet usandohibernate.connection.charSet.
Puede definir su propia estrategia plugin para obtener conexiones JDBC implementando la
interfazorg.hibernate.connection.ConnectionProvider y especificando su propia implementación personalizada
por medio de la propiedad hibernate.connection.provider_class.
3.4. Parámetros de configuración opcionales
Hay otras propiedades que controlan el comportamiento de Hibernate en tiempo de ejecución. Todas son
opcionales y tienen valores razonables por defecto.
AvisoAlgunas de estas propiedades se encuentran a "nivel del sistema sólamente". Las propiedades a
nivel del sistema sólamente se pueden establecer por medio de java -
Dproperty=value ohibernate.properties. No se pueden establecer por medio de las técnicas
descritas anteriormente.
Tabla 3.3. Propiedades de Configuración de Hibernate
Nombre de la propiedad Propósito
hibernate.dialect
El nombre de clase de un org.hibernate.dialect.Dialect de Hibernate, el cual le permite que genere un SQL optimizado para una base de datos relacional en particular.
e.g. full.classname.of.Dialect
En la mayoría de los casos Hibernate podrá de hecho seleccionar la implementación org.hibernate.dialect.Dialect correcta con base en losJDBC metadata que el controlador JDBC retorna.
hibernate.show_sql
Escribe todas las declaraciones SQL a la consola. Esta es una alternativa para establecer la categoria de registro org.hibernate.SQL adebug.
e.g. true | false
hibernate.format_sqlImprime el SQL en el registro y la consola. e.g. true | false
hibernate.default_schemaCalifica los nombres de tabla sin calificar con el esquema/espacio de tabla dado en el SQL generado. e.g. SCHEMA_NAME
hibernate.default_catalogCalifica los nombres de tabla sin calificar con el catálogo dado en el SQL generado. e.g. CATALOG_NAME
hibernate.session_factory_name
Automáticamente se vinculará el org.hibernate.SessionFactory a este nombre en JNDI después de que se ha creado.
e.g. jndi/composite/name
hibernate.max_fetch_depth
Establece una "profundidad" máxima del árbol de recuperación por unión externa (outer join) para asociaciones de un sólo extremo (uno-a-uno, muchos-a-uno). Un 0 deshabilita la recuperación por unión externa predeterminada.
ej. los valores recomendados entre 0 y 3
hibernate.default_batch_fetch_sizeEstablece un tamaño por defecto para la recuperación en lote de asociaciones de Hibernate. ej. valores recomendados 4, 8, 16
hibernate.default_entity_mode
Establece un modo predeterminado de representación de entidades para todas las sesiones abiertas desde esta SessionFactory
dynamic-map, dom4j, pojo
hibernate.order_updates Obliga a Hibernate a ordenar las actualizaciones SQL por el
Nombre de la propiedad Propósito
valor de la clave principal de los items a actualizar. Esto resultará en menos bloqueos de transacción en sistemas altamente concurrentes. e.g. true| false
hibernate.generate_statisticsDe habilitarse, Hibernate colectará estadísticas útiles para la afinación de rendimiento. e.g. true | false
hibernate.use_identifier_rollback
De habilitarse, cuando se borren los objetos las propiedades identificadoras generadas se resetearán a losvalores establecidos por defecto. e.g. true | false
hibernate.use_sql_comments
De activarse, Hibernate generará comentarios dentro del SQL, para una depuración más fácil, por defecto es false.
e.g. true | false
Tabla 3.4. Propiedades de JDBC y Conexiones de Hibernate
Nombre de la propiedad Propósito
hibernate.jdbc.fetch_sizeUn valor distinto de cero que determina el tamaño de recuperación de JDBC (llama a Statement.setFetchSize()).
hibernate.jdbc.batch_sizeUn valor distinto de cero habilita que Hibernate utilice las actualizaciones en lote de JDBC2. ej. valores recomendados entre5 y 30
hibernate.jdbc.batch_versioned_data
Set this property to true if your JDBC driver returns correct row counts from executeBatch(). It is usually safe to turn this option on. Hibernate will then use batched DML for automatically versioned data. Defaults to false.
e.g. true | false
hibernate.jdbc.factory_class
Selecciona un org.hibernate.jdbc.Batcher personalizado. La mayoría de las aplicaciones no necesitarán esta propiedad de configuración.
eg. classname.of.BatcherFactory
hibernate.jdbc.use_scrollable_resultset
Habilita a Hibernate para utilizar los grupos de resultados deslizables de JDBC2. Esta propiedad sólamente es necesaria cuando se utilizan conexiones JDBC provistas por el usuario. En el caso contrario Hibernate utiliza los metadatos de conexión. e.g.true | false
hibernate.jdbc.use_streams_for_binary
Utiliza flujos (streams) al escribir/leer tipos binary o serializablea/desde JDBC. Propiedad a nivel de sistema
e.g. true | false
hibernate.jdbc.use_get_generated_keys
Habilita el uso de PreparedStatement.getGeneratedKeys() de JDBC3 para recuperar claves generadas nativamente después de insertar. Requiere un controlador JDBC3+ y un JRE1.4+. Establézcalo como falso si su controlador tiene problemas con los generadores del identificador de Hibernate. Por defecto, se intenta determinar las capacidades del controlador utilizando los metadatos de conexión.
e.g. true|false
hibernate.connection.provider_class
EL nombre de clase de unorg.hibernate.connection.ConnectionProvider personalizado que proporcione conexiones JDBC a Hibernate.
e.g. classname.of.ConnectionProvider
hibernate.connection.isolation Establece el nivel de aislamiento de la transacción JDBC. Comprueba java.sql.Connection para valores significativos pero observe que la mayoría de las bases de datos no soportan todos los niveles de aislamiento y algunos definen nivekes de aislamiento adicionales y no estándares.
Nombre de la propiedad Propósito
e.g. 1, 2, 4, 8
hibernate.connection.autocommitHabilita un guardado automático (autocommit) para las conexiones JDBC en pool (no se recomienda). e.g. true | false
hibernate.connection.release_mode
Especifica el momento en que Hibernate debe liberar las conexiones JDBC. Por defecto, una conexión JDBC es retenida hasta que la sesión se cierra o se desconecta explícitamente. Para una fuente de datos JTA del servidor de aplicaciones, debe utilizarafter_statement para liberar agresivamente las conexiones después de cada llamada JDBC. Para una conexión no JTA, frecuentemente tiene sentido el liberar la conexión al final de cada transacción, el utilizarafter_transaction. auto escogerá after_statement para las estrategias de transacción JTA y CMT y after_transaction para la estrategia JDBC de transacción.
e.g. auto (default) | on_close | after_transaction | after_statement
This setting only affects Sessions returned fromSessionFactory.openSession. For Sessions obtained throughSessionFactory.getCurrentSession, the CurrentSessionContextimplementation configured for use controls the connection release mode for those Sessions. See Sección 2.5, “Sesiones contextuales”
hibernate.connection.<propertyName>
Pasar la propiedad JDBC <propertyName> aDriverManager.getConnection().
hibernate.jndi.<propertyName>Pasar la propiedad <propertyName> al InitialContextFactory JNDI.
Tabla 3.5. Propiedades de Caché de Hibernate
Nombre de la propiedad Propósito
hibernate.cache.provider_class
El nombre de clase de un CacheProvider personalizado.
e.g. classname.of.CacheProvider
hibernate.cache.use_minimal_puts
Optimiza la operación del caché de segundo nivel para minimizar escrituras, con el costo de lecturas más frecuentes. Esta configuración es más útil para cachés en clúster y en Hibernate3, está habilitado por defecto para implementaciones de caché en clúster. e.g. true|false
hibernate.cache.use_query_cache
Habilita el caché de consultas. Las consultas individuales todavía tienen que establecerse con cachés. e.g. true|false
hibernate.cache.use_second_level_cache
Se puede utilizar para deshabilitar por completo el caché de segundo nivel, que está habilitado por defecto para clases que especifican un mapeo <cache>.
e.g. true|false
hibernate.cache.query_cache_factory
El nombre de clase de una interfaz QueryCache personalizada, por defecto al StandardQueryCache incorporado.
e.g. classname.of.QueryCache
hibernate.cache.region_prefixUn prefijo que se debe utilizar para los nombres de región del caché de segundo nivel. e.g. prefix
hibernate.cache.use_structured_entries
Obliga a Hibernate a almacenar los datos en el caché de segundo nivel en un formato más amigable para personas. e.g. true|false
Tabla 3.6. Propiedades de Transacción de Hibernate
Nombre de la propiedad Propósito
hibernate.transaction.factory_class
El nombre de clase de un TransactionFactory a utilizar con la API de Transaction de Hibernate (por defecto esJDBCTransactionFactory).
e.g. classname.of.TransactionFactory
jta.UserTransaction
Un nombre JNDI utilizado por JTATransactionFactory para obtener la UserTransaction de JTA del servidor de aplicaciones.
e.g. jndi/composite/name
hibernate.transaction.manager_lookup_class
El nombre de clase de un TransactionManagerLookup. Se requiere cuando el chaché a nivel de MVJ está habilitado o cuando se utiliza un generador alto/bajo en un entorno JTA.
e.g. classname.of.TransactionManagerLookup
hibernate.transaction.flush_before_completion
If enabled, the session will be automatically flushed during the before completion phase of the transaction. Built-in and automatic session context management is preferred, seeSección 2.5, “Sesiones contextuales”.
e.g. true | false
hibernate.transaction.auto_close_session
If enabled, the session will be automatically closed during the after completion phase of the transaction. Built-in and automatic session context management is preferred, seeSección 2.5, “Sesiones contextuales”.
e.g. true | false
Tabla 3.7. Propiedades Misceláneas
Nombre de la propiedad Propósito
hibernate.current_session_context_class
Supply a custom strategy for the scoping of the "current"Session. See Sección 2.5, “Sesiones contextuales” for more information about the built-in strategies.
e.g. jta | thread | managed | custom.Class
hibernate.query.factory_class
Elige la implementación de análisis sintáctico HQL. ej.org.hibernate.hql.ast.ASTQueryTranslatorFactory oorg.hibernate.hql.classic.ClassicQueryTranslatorFactory
hibernate.query.substitutions
Se utiliza para mapear desde tokens en consultas Hibernate a tokens SQL. (por ejemplo, los tokens pueden ser nombres de función o literales). e.g.hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC
hibernate.hbm2ddl.auto
Exporta o valida automáticamente DDL de esquema a la base de datos cuando se crea la SessionFactory. Con create-drop se desechará el esquema de la base de datos cuando laSessionFactory se cierre explícitamente.
e.g. validate | update | create | create-drop
hibernate.bytecode.use_reflection_optimizer
Enables the use of bytecode manipulation instead of runtime reflection. This is a System-level property and cannot be set inhibernate.cfg.xml. Reflection can sometimes be useful when troubleshooting. Hibernate always requires either CGLIB or javassist even if you turn off the optimizer.
e.g. true | false
hibernate.bytecode.provider
Both javassist or cglib can be used as byte manipulation engines; the default is javassist.
e.g. javassist | cglib
3.4.1. Dialectos de SQL
Siempre configure la propiedad hibernate.dialect a la subclase correcta org.hibernate.dialect.Dialect para su
base de datos. Si especifica un dialecto, Hibernate utilizará valores predeterminados de manera sensible
para algunas de las otras propiedades enumeradas anteriormente, ahorrándole el esfuerzo de
especificarlas manualmente.
Tabla 3.8. Dialectos SQL de Hibernate(hibernate.dialect)
RDBMS Dialecto
DB2 org.hibernate.dialect.DB2Dialect
DB2 AS/400 org.hibernate.dialect.DB2400Dialect
DB2 OS390 org.hibernate.dialect.DB2390Dialect
PostgreSQL org.hibernate.dialect.PostgreSQLDialect
MySQL org.hibernate.dialect.MySQLDialect
MySQL con InnoDB org.hibernate.dialect.MySQLInnoDBDialect
MySQL con MyISAM org.hibernate.dialect.MySQLMyISAMDialect
Oracle (cualquier versión) org.hibernate.dialect.OracleDialect
Oracle 9i org.hibernate.dialect.Oracle9iDialect
Oracle 10g org.hibernate.dialect.Oracle10gDialect
Sybase org.hibernate.dialect.SybaseDialect
Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect
Microsoft SQL Server org.hibernate.dialect.SQLServerDialect
SAP DB org.hibernate.dialect.SAPDBDialect
Informix org.hibernate.dialect.InformixDialect
HypersonicSQL org.hibernate.dialect.HSQLDialect
Ingres org.hibernate.dialect.IngresDialect
Progress org.hibernate.dialect.ProgressDialect
Mckoi SQL org.hibernate.dialect.MckoiDialect
Interbase org.hibernate.dialect.InterbaseDialect
Pointbase org.hibernate.dialect.PointbaseDialect
FrontBase org.hibernate.dialect.FrontbaseDialect
Firebird org.hibernate.dialect.FirebirdDialect
3.4.2. Recuperación por Unión Externa - Outer Join Fetching
Si su base de datos soporta uniones externas del estilo ANSI, Oracle o Sybase, frecuentemente
la recuperación por unión externa aumentará el rendimiento limitando el número de llamadas a la base de
datos. La recuperación por unión externa permite que un gráfico completo de objetos conectados por
asociaciones muchos-a-uno, uno-a-muchos, muchos-a-muchos y uno-a-uno sea recuperado en un
sólo SELECT SQL.
La recuperación por unión externa puede ser deshabilitada globalmente estableciendo la
propiedadhibernate.max_fetch_depth como 0. Un valor de 1 o mayor habilita la recuperación por unión
externa para asociaciones uno-a-uno y muchos-a-uno que hayan sido mapeadas con fetch="join".
See Sección 20.1, “Estrategias de recuperación” for more information.
3.4.3. Flujos Binarios
Oracle limita el tamaño de arrays de byte que se puedan pasar a/desde su controlador JDBC. Si desea
utilizar instancias grandes de tipo binary o serializable, usted debe
habilitar hibernate.jdbc.use_streams_for_binary. Esta es una configuración a nivel de sistema sólamente.
3.4.4. Caché de segundo nivel y de lectura
The properties prefixed by hibernate.cache allow you to use a process or cluster scoped second-level cache
system with Hibernate. See the Sección 20.2, “El Caché de Segundo Nivel” for more information.
3.4.5. Sustitución de Lenguaje de Consulta
Puede definir nuevos tokens de consulta de Hibernate utilizando hibernate.query.substitutions. Por ejemplo:
hibernate.query.substitutions true=1, false=0
Esto causaría que los tokens true y false sean traducidos a literales enteros en el SQL generado.
hibernate.query.substitutions toLowercase=LOWER
Esto le permitiría renombrar la función LOWER de SQL.
3.4.6. Estadísticas de Hibernate
Si habilita hibernate.generate_statistics, Hibernate expondrá un número de métricas que son útiles al afinar
un sistema en ejecución por medio de SessionFactory.getStatistics(). Incluso se puede configurar Hibernate
para exponer estas estadísticas por medio de JMX. Lea el Javadoc de las interfaces
en org.hibernate.stats para obtener más información.
3.5. Registros de mensajes (Logging)
Hibernate utiliza Simple Logging Facade for Java (SLF4J) con el fin de registrar varios eventos del sistema.
SLF4J puede direccionar su salida de registro a varios marcos de trabajo de registro (NOP, Simple, log4j
versión 1.2, JDK 1.4 logging, JCL o logback) dependiendo de su enlace escogido. Con el fin de configurar el
registro necesitará slf4j-api.jar en su ruta de clase junto con el archivo jar para su enlace preferido - slf4j-
log4j12.jaren el caso de Log4J. Consulte la documentación SLF4J para obtener mayores detalles. Para usar
Log4j también necesitará poner un archivo log4j.properties en su ruta de clase. Un archivo de propiedades
de ejemplo se distribuye junto con Hibernate en el directorio src/.
Le recomendamos bastante que se familiarice con los mensajes de registro de Hibernate. Se ha trabajado
bastante para hacer que los registros de Hibernate sean tan detallados como sea posible, sin hacerlos
ilegibles. Es un dispositivo esencial en la resolución de problemas. Las categorías de registro más
interesantes son las siguientes:
Tabla 3.9. Categorías de Registro de Hibernate
Categoría Función
org.hibernate.SQLRegistra todas las declaraciones DML de SQL a medida que se ejecutan
org.hibernate.type Registra todos los parámetros JDBC
org.hibernate.tool.hbm2ddlRegistra todas las declaraciones DDL de SQL a medida que se ejecutan
org.hibernate.prettyRegistra el estado de todas las entidades (máximo 20 entidades) asociadas con la sesión en tiempo de limpieza (flush)
org.hibernate.cache Registra toda la actividad del caché de segundo nivel
org.hibernate.transaction Registra la actividad relacionada con la transacción
org.hibernate.jdbc Registra toda adquisición de recursos JDBC
org.hibernate.hql.ast.AST Regista los ASTs de HQL y SQL, durante análisis de consultas.
org.hibernate.secure Registra todas las peticiones de autorización JAAS
org.hibernateRegistra todo. Hay mucha información, pero es útil para la resolución de problemas
Al desarrollar aplicaciones con Hibernate, casi siempre debe trabajar con debug habilitado para la
categoríaorg.hibernate.SQL o, alternativamente, la propiedad hibernate.show_sql habilitada.
3.6. Implementación de una NamingStrategy
La interfaz org.hibernate.cfg.NamingStrategy le permite especificar un "estándar de nombrado" para objetos
de la base de datos y los elementos del esquema.
Puede proveer reglas para generar automáticamente identificadores de la base de datos a partir de
identificadores JDBC o para procesar nombres "lógicos" de columnas y tablas dadas en el archivo de
mapeo en nombres "físicos" de columnas y tablas. Esta funcionalidad ayuda a reducir la verborragia del
documento de mapeo, eliminando ruidos repetitivos (por ejemplo, prefijos TBL_). Hibernate utiliza una
estrategia por defecto bastante mínima.
Puede especificar una estrategia diferente llamando a Configuration.setNamingStrategy() antes de agregar los
mapeos:
SessionFactory sf = new Configuration()
.setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
.addFile("Item.hbm.xml")
.addFile("Bid.hbm.xml")
.buildSessionFactory();
org.hibernate.cfg.ImprovedNamingStrategy es una estrategia incorporada que puede ser un punto de partida
útil para algunas aplicaciones.
3.7. Archivo de configuración XML
Un enfoque alternativo de configuración es especificar una configuración completa en un archivo
llamadohibernate.cfg.xml. Este archivo se puede utilizar como un remplazo del archivo hibernate.properties o
en el caso de que ambos se encuentren presentes, para sobrescribir propiedades.
El archivo de configuración XML por defecto se espera en la raíz de su CLASSPATH. Este es un ejemplo:
<?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
>
La ventaja de este enfoque es la externalización de los nombres de los archivos de mapeo a la
configuración. Elhibernate.cfg.xml también es más práctico una vez que haya afinado el caché de Hibernate.
Puede escoger ya sea hibernate.properties o hibernate.cfg.xml. Ambos son equivalentes, excepto por los
beneficios de utilizar la sintaxis XML que mencionados anteriormente.
Con la configuración XML, iniciar Hibernate es tan simple como:
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Puede seleccionar un fichero de configuración XML diferente utilizando:
SessionFactory sf = new Configuration()
.configure("catdb.cfg.xml")
.buildSessionFactory();
3.8. Integración con Servidores de Aplicaciones J2EE
Hibernate tiene los siguientes puntos de integración con la infraestructura J2EE:
o Fuentes de datos administrados por el contenedor: Hibernate puede utilizar conexiones JDBC
administradas por el contenedor y provistas a través de JNDI. Usualmente,
un TransactionManagercompatible con JTA y un ResourceManager se ocupan de la administración de
transacciones (CMT), especialmente del manejo de transacciones distribuídas a través de varias
fuentes de datos. También puede demarcar los límites de las transacciones programáticamente
(BMT) o puede que quiera utilizar para esto la API opcional de Transaction de Hibernate para
mantener portátil su código.o Vinculación Automática JNDI: Hibernate puede vincular sus SessionFactory a JNDI después del inicio.
o Vinculación de Sesión JTA: La Session de Hibernate se puede vincular automáticamente al ámbito
de transacciones JTA. Simplemente busque la SessionFactory de JNDI y obténga la Session actual.
Deje que Hibernate se ocupe de vaciar y cerrar la Session cuando se complete su transacción JTA.
La demarcación de transacción puede ser declarativa (CMT) o programática
(BMT/UserTransaction).o Despliegue JMX: Si tiene un servidor de aplicaciones con capacidad para JMX (por ejemplo, JBoss
AS), puede escoger el desplegar Hibernate como un MBean administrado. Esto le ahorra el código
de una línea de inicio para construir su SessionFactory desde una Configuration. El contenedor iniciará
su HibernateService, e idealmente también cuidará de las dependencias entre servicios (la fuente de
datos debe estar disponible antes de que Hibernate inicie, etc).
Dependiendo de su entorno, podría tener que establecer la opción de
configuraciónhibernate.connection.aggressive_release como true si su servidor de aplicaciones muestra
excepciones "contención de conexión".
3.8.1. Configuración de la estrategia de transacción
La API de Session de Hibernate es independiente de cualquier demarcación de transacción en su
arquitectura. Si deja que Hibernate utilice JDBC directamente, a través de un pool de conexiones, puede
comenzar y acabar sus transacciones llamando la API de JDBC. Si ejecuta en un servidor de aplicaciones
J2EE, puede que quiera utilizar transacciones administradas por bean y llamar la API de JTA
y UserTransaction cuando sea necesario.
Para mantener su código portable entre estos dos (y otros) entornos le recomendamos la API
de Transaction de Hibernate, que envuelve y oculta el sistema subyacente. Tiene que especificar una clase
fábrica para las instancias de Transaction estableciendo la propiedad de
configuración hibernate.transaction.factory_class de Hibernate.
Existen tres opciones estándares o incorporadas:
org.hibernate.transaction.JDBCTransactionFactory
delega a transacciones de bases de datos (JDBC) (por defecto)
org.hibernate.transaction.JTATransactionFactory
delega a transacciones administradas por el contenedor si una transacción existente se encuentra en
proceso en este contexto (por ejemplo, un método de bean de sesión EJB). De otra manera, se inicia una
nueva transacción y se utilizan las transacciones administradas por bean.
org.hibernate.transaction.CMTTransactionFactory
delega a transacciones JTA administradas por el contenedor
También puede definir sus propias estrategias de transacción (por ejemplo, para un servicio de transacción
CORBA).
Algunas funcionalidades en Hibernate (por ejemplo, el caché de segundo nivel, las sesiones contextuales,
etc.) requieren acceso al TransactionManager de JTA en un entorno administrado. En un servidor de
aplicaciones tiene que especificar cómo Hibernate debe obtener una referencia al TransactionManager, ya
que J2EE no estandariza un sólo mecanismo:
Tabla 3.10. TransactionManagers de JTA
Transaction FactoryServidor de Aplicaciones
org.hibernate.transaction.JBossTransactionManagerLookup JBoss
org.hibernate.transaction.WeblogicTransactionManagerLookup Weblogic
org.hibernate.transaction.WebSphereTransactionManagerLookup WebSphere
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup WebSphere 6
org.hibernate.transaction.OrionTransactionManagerLookup Orion
org.hibernate.transaction.ResinTransactionManagerLookup Resin
org.hibernate.transaction.JOTMTransactionManagerLookup JOTM
org.hibernate.transaction.JOnASTransactionManagerLookup JOnAS
org.hibernate.transaction.JRun4TransactionManagerLookup JRun4
org.hibernate.transaction.BESTransactionManagerLookup Borland ES
3.8.2. SessionFactory enlazado a JNDI
Una SessionFactory de Hibernate vinculada a JNDI puede simplificar la búsqueda de la fábrica y la creación
de nuevas Sessiones. Sin embargo, esto no se relaciona con un Datasource vinculado a JNDI; simplemente
que ambos utilizan el mismo registro.
Si desea tener la SessionFactory vinculada a un espacio de nombres de JNDI, especifique un nombre (por
ejemplo, java:hibernate/SessionFactory) utilizando la propiedad hibernate.session_factory_name. Si se omite esta
propiedad, la SessionFactory no será vinculada a JNDI. Esto es particularmente útil en entornos con una
implementación JNDI de sólo lectura por defecto (por ejemplo, en Tomcat).
Al vincular la SessionFactory a JNDI, Hibernate utilizará los valores de hibernate.jndi.url, hibernate.jndi.class para
instanciar un contexto inicial. Si éstos no se especifican, se utilizará el InitialContext por defecto.
Hibernate colocará automáticamente la SessionFactory en JNDI después de que llame
acfg.buildSessionFactory(). Esto significa que tendrá al menos esta llamada en algún código de inicio o clase
de utilidad en su aplicación, a menos de que utilice el despliegue JMX con el HibernateService (esto se
discute más adelante en mayor detalle).
Si utiliza una SessionFactory JNDI, un EJB or cualquier otra clase puede llegar a obtener
el SessionFactoryutilizando una búsqueda JNDI.
Le recomendamos que vincule el SessionFactory a JNDI en un entorno administrado y que de otra manera,
use un singleton static. Para proteger su código de aplicación de estos detalles, también le recomendamos
que esconda el código de búsqueda real para una SessionFactory en una clase de ayuda
comoHibernateUtil.getSessionFactory(). Note que dicha clase también es una manera práctica de iniciar
Hibernate— vea el capítulo 1.
3.8.3. Administración de contexto de Sesión Actual con JTA
The easiest way to handle Sessions and transactions is Hibernate's automatic
"current" Session management. For a discussion of contextual sessions see Sección 2.5, “Sesiones
contextuales”. Using the "jta" session context, if there is no Hibernate Session associated with the current
JTA transaction, one will be started and associated with that JTA transaction the first time you
call sessionFactory.getCurrentSession(). The Sessions retrieved via getCurrentSession() in the "jta" context are set
to automatically flush before the transaction completes, close after the transaction completes, and
aggressively release JDBC connections after each statement. This allows the Sessions to be managed by the
life cycle of the JTA transaction to which it is associated, keeping user code clean of such management
concerns. Your code can either use JTA programmatically through UserTransaction, or (recommended for
portable code) use the Hibernate TransactionAPI to set transaction boundaries. If you run in an EJB
container, declarative transaction demarcation with CMT is preferred.
3.8.4. Despliegue JMX
La línea cfg.buildSessionFactory() todavía se tiene que ejecutar en algún sitio para obtener
una SessionFactoryen JNDI. Puede hacer esto ya sea en un bloque inicializador static (como aquel
en HibernateUtil) o bien puede desplegar Hibernate como un servicio administrado.
Hibernate se distribuye con org.hibernate.jmx.HibernateService para desplegar 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 ejemplo de jboss-service.xml para JBoss 4.0.x:
<?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
>
Este archivo se implementa en un directorio llamado META-INF y se encuentra empacado en un archivo JAR
con la extensión .sar (archivo de servicio). También necesita empacar Hibernate, sus bibliotecas de
terceros requeridas, sus clases persistentes compiladas, así como sus archivos de mapeo en el mismo
archivo. Sus beans empresariales (usualmente beans de sesión) se pueden dejar en su propio archivo JAR,
pero puede incluir este archivo EJB JAR en el archivo de servicio principal para obtener una unidad
desplegable en vivo (sin apagarlo). Consulte la documentación de JBoss AS para obtener más información
sobre el servicio JMX y la implementación de EJB.
Copyright © 2004 Red Hat, Inc.