Ricerca…


Osservazioni

Il bean SessionFactory è responsabile della creazione, della manutenzione, della chiusura e dello svuotamento di tutte le sessioni del database che TransactionManager richiede di creare. Ecco perché autowire SessionFactory in DAO e fare eseguire tutte le query attraverso di esso.

Una delle domande più importanti che i nuovi utenti di Hibernate chiedono è "Quando vengono eseguite le mie modifiche?" e la risposta ha senso quando si pensa a come TransactionManager funziona con SesisonFactory . Le modifiche al database verranno svuotate e impegnate quando si esce dal metodo di servizio annotato con @Transactional . La ragione di ciò è che una transazione dovrebbe rappresentare una singola 'unità' di lavoro ininterrotto. Se qualcosa va storto con l'unità, allora si presume che l'unità abbia fallito e tutte le modifiche dovrebbero essere ripristinate. Quindi SessionFactory cancellerà e cancellerà la sessione quando esci dal metodo di servizio che hai chiamato in origine.

Questo non vuol dire che non svuoterà e cancellerà la sessione mentre la transazione è in corso. Ad esempio, se chiamo un metodo di servizio per aggiungere una raccolta di 5 oggetti e restituisco il conteggio totale degli oggetti nel database, SessionFactory si renderà conto che la query ( SELECT COUNT(*) ) richiede che uno stato aggiornato sia accurato e quindi svuoterebbe l'aggiunta dei 5 oggetti prima di eseguire la query di conteggio. L'esecuzione potrebbe essere simile a questa:

Versioni

Versione Link alla documentazione Data di rilascio
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

Utilizzo della configurazione XML per configurare Hibernate

Creo un file chiamato database-servlet.xml da qualche parte sul classpath.

Inizialmente il tuo file di configurazione sarà simile a questo:

<?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>

Noterai che ho importato i namespace tx e jdbc Spring. Questo perché li useremo abbastanza pesantemente in questo file di configurazione.

La prima cosa che vuoi fare è abilitare la gestione delle transazioni basata sull'annotazione ( @Transactional ). La ragione principale per cui le persone usano Hibernate in primavera è perché Spring gestirà tutte le transazioni per te. Aggiungi la seguente riga al tuo file di configurazione:

<tx:annotation-driven />

Abbiamo bisogno di creare una fonte di dati. L'origine dati è fondamentalmente il database che Hibernate utilizzerà per mantenere i tuoi oggetti. Generalmente un gestore delle transazioni avrà un'origine dati. Se vuoi che Hibernate parli con più fonti di dati, allora hai più gestori di transazioni.

<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 classe di questo bean può essere qualsiasi cosa che implementa javax.sql.DataSource modo che tu possa scrivere la tua. Questa classe di esempio è fornita da Spring, ma non ha un proprio pool di thread. Un'alternativa popolare è Apache Commons org.apache.commons.dbcp.BasicDataSource , ma ce ne sono molti altri. Spiegherò ognuna delle proprietà qui sotto:

  • driverClassName : il percorso del driver JDBC. Questo è un JAR specifico del database che dovrebbe essere disponibile sul classpath. Assicurati di avere la versione più aggiornata. Se si utilizza un database Oracle, è necessario un OracleDriver. Se hai un database MySQL, avrai bisogno di un MySQLDriver. Vedi se riesci a trovare il driver che ti serve qui, ma un google veloce dovrebbe darti il ​​driver corretto.

  • url : l'URL del tuo database. Di solito questo sarà qualcosa come jdbc\:oracle\:thin\:\path\to\your\database o jdbc:mysql://path/to/your/database . Se cerchi google in giro per il percorso predefinito del database che stai utilizzando, dovresti essere in grado di scoprire cosa dovrebbe essere. Se ricevi una HibernateException con il messaggio org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set e stai seguendo questa guida, c'è il 90% di possibilità che il tuo URL sia sbagliato, una probabilità del 5% che il tuo database non è stato avviato e un 5% di probabilità che il tuo nome utente / password sia sbagliato.

  • username : il nome utente da utilizzare durante l'autenticazione con il database.

  • password : la password da utilizzare durante l'autenticazione con il database.

La prossima cosa è impostare SessionFactory . Questa è la cosa che Hibernate usa per creare e gestire le tue transazioni e in effetti parla con il database. Ha parecchie opzioni di configurazione che cercherò di spiegare sotto.

<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 : il tuo bean di origine dati. Se hai cambiato l'Id di dataSource, impostalo qui.

  • packagesToScan : i pacchetti da scansionare per trovare gli oggetti annotati JPA. Questi sono gli oggetti che la factory di sessione deve gestire, generalmente saranno POJO e annotati con @Entity . Per ulteriori informazioni su come impostare le relazioni tra oggetti in Hibernate, vedere qui .

  • annotatedClasses (non mostrato): puoi anche fornire un elenco di classi per Hibernate da analizzare se non sono tutte nello stesso pacchetto. Dovresti usare i packagesToScan annotatedClasses o annotatedClasses ma non entrambi. La dichiarazione assomiglia a questo:

<property name="annotatedClasses">
    <list>
        <value>foo.bar.package.model.Person</value>
        <value>foo.bar.package.model.Thing</value>
    </list>
</property>
  • HibernateProperties : ci sono una miriade di questi documenti amorevolmente documentati qui . I principali che userete sono i seguenti:
  • hibernate.hbm2ddl.auto : una delle domande più calde di Hibernate descrive questa proprietà. Guardalo per maggiori informazioni Generalmente utilizzo validate e configuro il mio database usando gli script SQL (per una memoria in-house) o creando preventivamente il database (database esistente).
  • hibernate.show_sql : Boolean flag, se true Hibernate stamperà tutto lo SQL che genera sullo stdout . Puoi anche configurare il tuo logger per mostrare i valori che sono associati alle query impostando log4j.logger.org.hibernate.type=TRACE log4j.logger.org.hibernate.SQL=DEBUG nel tuo log manager (io uso log4j ).
  • hibernate.format_sql : Boolean flag, farà in modo che Hibernate stampa piuttosto il tuo SQL sullo stdout.
  • hibernate.dialect (non mostrato, per una buona ragione): un sacco di vecchi tutorial là fuori ti mostrano come impostare il dialetto Hibernate che userà per comunicare con il tuo database. Hibernate può rilevare automaticamente quale dialetto utilizzare in base al driver JDBC che si sta utilizzando. Dato che ci sono circa 3 diversi dialetti Oracle e 5 diversi dialetti MySQL, lascerei questa decisione fino a Hibernate. Per un elenco completo dei dialetti, i supporti di Hibernate vedono qui .

Gli ultimi 2 fagioli che devi dichiarare sono:

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

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

PersistenceExceptionTranslator traduce le specifiche HibernateException o SQLExceptions specifiche del database in eccezioni Spring che possono essere comprese dal contesto dell'applicazione.

Il bean TransactionManager è ciò che controlla le transazioni e i rollback.

Nota: è necessario automatizzare il bean SessionFactory nei DAO.

Configurazione di Hibernate senza XML

Questo esempio è stato preso da qui

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();
    }

    
}

Si noti che con l'ultima versione di Hibernate questo approccio non funziona bene (la versione di Hibernate 5.2 consente comunque questa configurazione)

Esempio di ibernazione semplice con XML

Per impostare un semplice progetto di ibernazione utilizzando XML per le configurazioni sono necessari 3 file, hibernate.cfg.xml, un POJO per ogni entità e un EntityName.hbm.xml per ogni entità. Ecco un esempio di ciascun utilizzo di 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 e testPassword saranno tutti sostituiti. Assicurati di utilizzare il nome completo della risorsa se si trova in un pacchetto.

Employee.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>

Di nuovo, se la classe è in un pacchetto usa il nome completo della classe nomepacchetto.className.

Dopo aver questi tre file sei pronto per l'uso di ibernazione nel tuo progetto.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow