Looking for hibernate Keywords? Try Ask4Keywords

hibernateEmpezando con hibernar


Observaciones

El bean SessionFactory es responsable de crear, mantener, cerrar y vaciar todas las sesiones de base de datos que el TransactionManager le pide que cree. Es por eso que creamos automáticamente SessionFactory en DAO y hacemos que todas las consultas se realicen a través de él.

Una de las mayores preguntas que hacen los nuevos usuarios de Hibernate es "¿Cuándo se comprometen mis cambios?" y la respuesta tiene sentido cuando piensa cómo funciona el TransactionManager con SesisonFactory . Los cambios en la base de datos se borrarán y se confirmarán cuando salga del método de servicio anotado con @Transactional . La razón de esto es que se supone que una transacción representa una única 'unidad' de trabajo ininterrumpido. Si algo sale mal con la unidad, se asume que la unidad falló y todos los cambios deberían revertirse. Por lo tanto, SessionFactory vaciará y borrará la sesión cuando salga del método de servicio al que llamó originalmente.

Eso no quiere decir que no se vaciará ni borrará la sesión mientras se realiza la transacción. Por ejemplo, si llamo a un método de servicio para agregar una colección de 5 objetos y devolver el recuento total de objetos en la base de datos, SessionFactory daría cuenta de que la consulta ( SELECT COUNT(*) ) requiere un estado actualizado para ser precisa, y así se eliminaría la adición de los 5 objetos antes de ejecutar la consulta de conteo. La ejecución podría verse algo así:

Versiones

Versión Enlace de documentación Fecha de lanzamiento
4.2.0 http://hibernate.org/orm/documentation/4.2/ 2013-03-01
4.3.0 http://hibernate.org/orm/documentation/4.3/ 2013-12-01
5.0.0 http://hibernate.org/orm/documentation/5.0/ 2015-09-01

Ejemplo de hibernación simple usando XML

Para configurar un proyecto de hibernación simple utilizando XML para las configuraciones, necesita 3 archivos, hibernate.cfg.xml, un POJO para cada entidad y un EntityName.hbm.xml para cada entidad. Aquí hay un ejemplo de cada uno usando MySQL:

hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC 
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>
   <property name="hibernate.dialect">
      org.hibernate.dialect.MySQLDialect
   </property>
   <property name="hibernate.connection.driver_class">
      com.mysql.jdbc.Driver
   </property>

   <property name="hibernate.connection.url">
      jdbc:mysql://localhost/DBSchemaName
   </property>
   <property name="hibernate.connection.username">
      testUserName
   </property>
   <property name="hibernate.connection.password">
      testPassword
   </property>

   <!-- List of XML mapping files -->
   <mapping resource="HibernatePractice/Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>
 

DBSchemaName, testUserName y testPassword serían reemplazados. Asegúrese de usar el nombre completo del recurso si está en un paquete.

Empleado.java

package HibernatePractice;

public class Employee {
    private int id;
    private String firstName;
    private String middleName;
    private String lastName;
    
    public Employee(){
        
    }
    public int getId(){
        return id;
    }
    public void setId(int id){
        this.id = id;
    }
    public String getFirstName(){
        return firstName;
    }
    public void setFirstName(String firstName){
        this.firstName = firstName;
    }
    public String getMiddleName(){
        return middleName;
    }
    public void setMiddleName(String middleName){
        this.middleName = middleName;
    }
    public String getLastName(){
        return lastName;
    }
    public void setLastName(String lastName){
        this.lastName = lastName;
    }
}
 

Employee.hbm.xml

<hibernate-mapping>
   <class name="HibernatePractice.Employee" table="employee">
      <meta attribute="class-description">
         This class contains employee information. 
      </meta>
      <id name="id" type="int" column="empolyee_id">
         <generator class="native"/>
      </id>
      <property name="firstName" column="first_name" type="string"/>
      <property name="middleName" column="middle_name" type="string"/>
      <property name="lastName" column="last_name" type="string"/>
   </class>
</hibernate-mapping>
 

Nuevamente, si la clase está en un paquete, use el nombre completo de la clase packageName.className.

Una vez que tenga estos tres archivos, estará listo para usar la hibernación en su proyecto.

Usando la configuración XML para configurar Hibernate

Creo un archivo llamado database-servlet.xml algún lugar de la ruta de database-servlet.xml .

Inicialmente, su archivo de configuración se verá así:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

</beans>
 

Notarás que jdbc espacios de nombre tx y jdbc Spring. Esto se debe a que los vamos a utilizar bastante en este archivo de configuración.

Lo primero que debe hacer es habilitar la gestión de transacciones basada en anotaciones ( @Transactional ). La razón principal por la que las personas usan Hibernate en Spring es porque Spring administrará todas sus transacciones por usted. Agregue la siguiente línea a su archivo de configuración:

<tx:annotation-driven />
 

Necesitamos crear una fuente de datos. El origen de datos es básicamente la base de datos que Hibernate usará para conservar sus objetos. En general, un administrador de transacciones tendrá un origen de datos. Si desea que Hibernate hable con múltiples fuentes de datos, tiene múltiples administradores de transacciones.

<bean id="dataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="" />
    <property name="url" value="" />
    <property name="username" value="" />
    <property name="password" value="" />
</bean>
 

La clase de este bean puede ser cualquier cosa que implemente javax.sql.DataSource para que puedas escribir el tuyo. Esta clase de ejemplo es proporcionada por Spring, pero no tiene su propio grupo de subprocesos. Una alternativa popular es el Apache Commons org.apache.commons.dbcp.BasicDataSource , pero hay muchos otros. Voy a explicar cada una de las propiedades a continuación:

  • driverClassName : la ruta a su controlador JDBC. Este es un JAR específico para la base de datos que debería estar disponible en su classpath. Asegúrese de tener la versión más actualizada. Si está utilizando una base de datos Oracle, necesitará un OracleDriver. Si tiene una base de datos MySQL, necesitará un MySQLDriver. Vea si puede encontrar el controlador que necesita aquí, pero un google rápido le dará el controlador correcto.

  • url : La URL de su base de datos. Normalmente esto será algo como jdbc\:oracle\:thin\:\path\to\your\database o jdbc:mysql://path/to/your/database . Si busca en Google la ubicación predeterminada de la base de datos que está utilizando, debería poder averiguar cuál debería ser. Si obtiene una HibernateException con el mensaje org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set y está siguiendo esta guía, hay un 90% de probabilidad de que su URL sea incorrecta, un 5% de probabilidad que su base de datos no se haya iniciado y un 5% de probabilidad de que su nombre de usuario / contraseña sea incorrecto.

  • nombre de usuario : el nombre de usuario que se usará cuando se autentique con la base de datos.

  • contraseña : la contraseña que se utilizará al autenticarse con la base de datos.

Lo siguiente, es configurar el SessionFactory . Esto es lo que Hibernate usa para crear y administrar sus transacciones, y en realidad habla con la base de datos. Tiene bastantes opciones de configuración que trataré de explicar a continuación.

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="au.com.project />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.use_sql_comments">true</prop>
            <prop key="hibernate.hbm2ddl.auto">validate</prop>
        </props>
    </property>
</bean>
 
  • dataSource: Su grano de fuente de datos. Si cambió la ID de la fuente de datos, configúrela aquí.

  • packagesToScan : los paquetes a escanear para encontrar sus objetos anotados JPA. Estos son los objetos que la fábrica de sesiones necesita gestionar, generalmente serán POJO y anotados con @Entity . Para obtener más información sobre cómo configurar relaciones de objetos en Hibernate, consulte aquí .

  • annotatedClasses (no se muestra): también puede proporcionar una lista de clases para que Hibernate las explore si no están todas en el mismo paquete. Debes usar packagesToScan o annotatedClasses pero no ambos. La declaración se ve así:

<property name="annotatedClasses">
    <list>
        <value>foo.bar.package.model.Person</value>
        <value>foo.bar.package.model.Thing</value>
    </list>
</property>
 
  • hibernateProperties : Hay una gran cantidad de estos documentados aquí con amor. Los principales que utilizará son los siguientes:
  • hibernate.hbm2ddl.auto : Una de las preguntas más importantes de Hibernate detalla esta propiedad. Véalo para más información . Generalmente uso validar, y configuro mi base de datos usando scripts SQL (para una memoria interna), o creo la base de datos de antemano (base de datos existente).
  • hibernate.show_sql : indicador booleano, si es verdadero, Hibernate imprimirá todo el SQL que genere en la stdout . También puede configurar su registrador para que le muestre los valores que están vinculados a las consultas configurando log4j.logger.org.hibernate.type=TRACE log4j.logger.org.hibernate.SQL=DEBUG en su administrador de registros (yo uso log4j ).
  • hibernate.format_sql : bandera booleana, hará que Hibernate imprima bastante su SQL a la salida estándar.
  • hibernate.dialect (No se muestra, por una buena razón): muchos de los tutoriales antiguos que hay por ahí le muestran cómo configurar el dialecto de Hibernate que usará para comunicarse con su base de datos. Hibernate puede detectar automáticamente qué dialecto usar según el controlador JDBC que está utilizando. Como hay alrededor de 3 dialectos de Oracle diferentes y 5 dialectos de MySQL diferentes, dejaría esta decisión en manos de Hibernate. Para obtener una lista completa de los dialectos compatibles con Hibernate, consulte aquí .

Los 2 últimos frijoles que debes declarar son:

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"
    id="PersistenceExceptionTranslator" />

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
 

El PersistenceExceptionTranslator traduce HibernateException o SQLExceptions específicas de la base de datos en excepciones Spring que pueden ser comprendidas por el contexto de la aplicación.

El bean TransactionManager es lo que controla las transacciones, así como los retrocesos.

Nota: debe auto cablear su bean SessionFactory a sus DAO.

Configuración de hibernación sin XML

Este ejemplo ha sido tomado de aquí.

package com.reborne.SmartHibernateConnector.utils;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class LiveHibernateConnector implements IHibernateConnector {

    private String DB_DRIVER_NAME = "";
    private String DB_URL = "jdbc:h2:~/liveDB;MV_STORE=FALSE;MVCC=FALSE";
    private String DB_USERNAME = "sa";
    private String DB_PASSWORD = "";
    private String DIALECT = "org.hibernate.dialect.H2Dialect";
    private String HBM2DLL = "create";
    private String SHOW_SQL = "true";
    
    private static Configuration config;
    private static SessionFactory sessionFactory;
    private Session session;
    
    private boolean CLOSE_AFTER_TRANSACTION = false;

    public LiveHibernateConnector() {
        
        config = new Configuration();

        config.setProperty("hibernate.connector.driver_class",         DB_DRIVER_NAME);
        config.setProperty("hibernate.connection.url",                 DB_URL);
        config.setProperty("hibernate.connection.username",         DB_USERNAME);
        config.setProperty("hibernate.connection.password",         DB_PASSWORD);
        config.setProperty("hibernate.dialect",                     DIALECT);
        config.setProperty("hibernate.hbm2dll.auto",                 HBM2DLL);
        config.setProperty("hibernate.show_sql",                    SHOW_SQL);
    
        /*
         * Config connection pools
         */

        config.setProperty("connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider");
        config.setProperty("hibernate.c3p0.min_size", "5");
        config.setProperty("hibernate.c3p0.max_size", "20");
        config.setProperty("hibernate.c3p0.timeout", "300");
        config.setProperty("hibernate.c3p0.max_statements", "50");
        config.setProperty("hibernate.c3p0.idle_test_period", "3000");
        
        
        /**
         * Resource mapping
         */
        
//        config.addAnnotatedClass(User.class);
//        config.addAnnotatedClass(User.class);
//        config.addAnnotatedClass(User.class);
    
        sessionFactory = config.buildSessionFactory();
    }


    public HibWrapper openSession() throws HibernateException {
        return new HibWrapper(getOrCreateSession(), CLOSE_AFTER_TRANSACTION);
    }


    public Session getOrCreateSession() throws HibernateException {
        if (session == null) {
            session = sessionFactory.openSession();
        }
        return session;
    }

    public void reconnect() throws HibernateException {
        this.sessionFactory = config.buildSessionFactory();
    }

    
}
 

Tenga en cuenta que con la última versión de Hibernate este enfoque no funciona bien (la versión 5.2 de Hibernate todavía permite esta configuración)