Spring est l’un des frameworks Java EE les plus utilisés et Hibernate est le framework ORM le plus populaire. C’est pourquoi la combinaison Spring Hibernate est largement utilisée dans les applications d’entreprise. Récemment, j’ai beaucoup écrit sur Spring Tutorial et Hibernate Tutorial, donc un article sur l’intégration Spring Hibernate était nécessaire depuis longtemps.
Spring Hibernate
Aujourd’hui dans ce tutoriel, nous utiliserons Spring 4 et l’intégrerons avec Hibernate 3, puis mettrons à jour le même projet pour utiliser Hibernate 4. Comme il existe de nombreuses versions de Spring et Hibernate et que l’artefact Spring ORM prend en charge à la fois Hibernate 3 et Hibernate 4, il est bon que je liste toutes les dépendances que j’ai utilisées dans mon projet. Notez que j’ai remarqué que toutes les versions de Spring et Hibernate ne sont pas compatibles, les versions ci-dessous ont fonctionné pour moi, donc je pense qu’elles sont compatibles. Si vous utilisez d’autres versions et obtenez une erreur « java.lang.NoClassDefFoundError », cela signifie qu’elles ne sont pas compatibles. C’est principalement parce que les classes Hibernate ont été déplacées d’un package à un autre, provoquant cette erreur. Par exemple, la classe « org.hibernate.engine.FilterDefinition » a été déplacée vers « org.hibernate.engine.spi.FilterDefinition » dans les dernières versions de Hibernate.
- Version du Framework Spring : 4.0.3.RELEASE
- Version de Hibernate Core et Hibernate EntityManager : 3.6.9.Final et 4.3.5.Final
- Version de Spring ORM : 4.0.3.RELEASE
Configuration de la base de données
I am using MySQL database for my project, so below setup.sql script will create the necessary table for this example.
CREATE TABLE `Person` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '',
`country` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
commit;
Structure du projet d’exemple d’intégration Spring Hibernate
L’image ci-dessous montre la structure finale du projet, nous examinerons chaque composant un par un.
Dépendances Maven
Nous allons d’abord examiner notre fichier pom.xml pour toutes les dépendances requises et leurs versions.
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.samples</groupId>
<artifactId>SpringHibernateExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!-- Generic properties -->
<java.version>1.6</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring -->
<spring-framework.version>4.0.3.RELEASE</spring-framework.version>
<!-- Hibernate / JPA -->
<!-- <hibernate.version>4.3.5.Final</hibernate.version> -->
<hibernate.version>3.6.9.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
</properties>
<dependencies>
<!-- Spring and Transactions -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Spring ORM support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Logging with SLF4J & LogBack -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
</project>
Les dépendances importantes pour le projet d’intégration de Spring et Hibernate sont :
- spring-context et spring-tx pour les fonctionnalités principales de Spring. Remarquez que j’utilise la version 4.0.3.RELEASE.
- La dépendance spring-orm pour le support Spring ORM, elle est nécessaire pour l’intégration de Hibernate dans notre projet Spring.
- Les dépendances hibernate-entitymanager et hibernate-core pour le framework Hibernate. Remarquez que la version est 3.6.9.Final, pour utiliser Hibernate 4, tout ce dont nous avons besoin est de la changer en 4.3.5.Final comme indiqué dans le fichier pom.xml ci-dessus.
- mysql-connector-java pour le pilote MySQL pour la connexion à la base de données.
Classe de modèle ou entité
Nous pouvons utiliser le mapping basé sur XML de Hibernate ainsi que le mapping basé sur les annotations JPA. Ici, j’utilise les annotations JPA pour le mapping car Hibernate fournit une implémentation JPA.
package com.journaldev.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Entity bean with JPA annotations
* Hibernate provides JPA implementation
* @author pankaj
*
*/
@Entity
@Table(name="Person")
public class Person {
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
private String country;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString(){
return "id="+id+", name="+name+", country="+country;
}
}
Classes DAO
Nous implémenterons deux méthodes dans nos classes DAO, d’abord pour sauvegarder l’objet Personne dans la table et deuxièmement qui récupérera tous les enregistrements de la table et renverra la liste des Personnes.
package com.journaldev.dao;
import java.util.List;
import com.journaldev.model.Person;
public interface PersonDAO {
public void save(Person p);
public List<Person> list();
}
L’implémentation de la classe DAO ci-dessus ressemblerait à ceci.
package com.journaldev.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.journaldev.model.Person;
public class PersonDAOImpl implements PersonDAO {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void save(Person p) {
Session session = this.sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.persist(p);
tx.commit();
session.close();
}
@SuppressWarnings("unchecked")
@Override
public List<Person> list() {
Session session = this.sessionFactory.openSession();
List<Person> personList = session.createQuery("from Person").list();
session.close();
return personList;
}
}
Remarquez que c’est le seul endroit où nous utilisons des classes liées à Hibernate. Ce modèle rend notre implémentation flexible et facile à migrer d’une technologie à une autre. Par exemple, si nous voulons utiliser le framework ORM iBatis, tout ce dont nous avons besoin est de fournir une implémentation DAO pour iBatis, puis de modifier le fichier de configuration du bean Spring. Dans l’exemple ci-dessus, j’utilise la gestion des transactions de session Hibernate. Mais nous pouvons également utiliser la gestion des transactions déclaratives de Spring en utilisant l’annotation @Transactional
, en savoir plus sur Gestion des transactions Spring.
Fichier de configuration du bean Spring pour l’intégration de Hibernate 3
Commençons d’abord par examiner les configurations de bean de printemps dont nous avons besoin pour l’intégration de Hibernate 3. Nous examinerons les détails plus en détail plus tard.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:aop="https://www.springframework.org/schema/aop"
xmlns:tx="https://www.springframework.org/schema/tx"
xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.0.xsd
https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/TestDB" />
<property name="username" value="pankaj" />
<property name="password" value="pankaj123" />
</bean>
<!-- Hibernate 3 XML SessionFactory Bean definition-->
<!-- <bean id="hibernate3SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>person.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
</value>
</property>
</bean> -->
<!-- Hibernate 3 Annotation SessionFactory Bean definition-->
<bean id="hibernate3AnnotatedSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.journaldev.model.Person</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="personDAO" class="com.journaldev.dao.PersonDAOImpl">
<property name="sessionFactory" ref="hibernate3AnnotatedSessionFactory" />
</bean>
</beans>
Il existe deux façons de fournir les détails de connexion à la base de données à Hibernate, soit en passant tout dans hibernateProperties
, soit en créant un DataSource et en le passant à Hibernate. Je préfère la deuxième approche, c’est pourquoi nous avons la dépendance Apache Commons DBCP pour créer un BasicDataSource
en définissant les propriétés de connexion à la base de données. Pour l’intégration de Spring et Hibernate 3, Spring ORM fournit deux classes – org.springframework.orm.hibernate3.LocalSessionFactoryBean
lorsque les mappages Hibernate sont basés sur XML et org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
pour les mappages basés sur les annotations. J’ai fourni une configuration de bean simple de LocalSessionFactoryBean
en commentaires, si vous utilisez des mappages basés sur XML. AnnotationSessionFactoryBean
étend la classe LocalSessionFactoryBean
, elle possède donc toutes les propriétés de base pour l’intégration de Hibernate. Les propriétés sont auto-explicatives et principalement liées à Hibernate, je n’entrerai donc pas dans les détails pour elles. Mais si vous vous demandez d’où proviennent les hibernateProperties et annotatedClasses, vous devez consulter le code source de la classe de bean. Remarquez la définition de bean de personDAO, comme je l’ai dit précédemment, si nous devons passer à un autre framework ORM, nous devons changer la classe d’implémentation ici et définir d’autres propriétés dont nous avons besoin.
Programme de test Spring 4 Hibernate 3
Notre configuration est maintenant prête, écrivons un programme simple pour tester notre application.
package com.journaldev.main;
import java.util.List;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.journaldev.dao.PersonDAO;
import com.journaldev.model.Person;
public class SpringHibernateMain {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
PersonDAO personDAO = context.getBean(PersonDAO.class);
Person person = new Person();
person.setName("Pankaj"); person.setCountry("India");
personDAO.save(person);
System.out.println("Person::"+person);
List list = personDAO.list();
for(Person p : list){
System.out.println("Person List::"+p);
}
// fermer les ressources
context.close();
}
}
Lorsque nous exécutons le programme ci-dessus, nous obtenons beaucoup de sorties liées à Hibernate car je n’ai pas configuré correctement le journal, mais cela dépasse le cadre de ce tutoriel. Cependant, nous obtenons la sortie suivante générée par notre programme.
Person::id=3, name=Pankaj, country=India
Person List::id=1, name=Pankaj, country=India
Person List::id=2, name=Pankaj, country=India
Person List::id=3, name=Pankaj, country=India
Changements d’intégration Spring 4 Hibernate 4
Modifions maintenant notre application pour utiliser Hibernate 4 au lieu de Hibernate 3. Pour cette migration, nous devons effectuer uniquement les changements de configuration suivants.
-
Changez la version de Hibernate en 4.3.5.Final dans le fichier pom.xml, comme indiqué dans les commentaires ci-dessus.
-
Modifiez le fichier de configuration du bean Spring, jusqu’à présent vous devez avoir compris que le fichier de configuration du bean Spring est la clé de l’intégration du framework Spring et Hibernate. Le fichier de configuration du bean Spring ci-dessous fonctionnera pour les versions Spring 4 et Hibernate 4.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://www.springframework.org/schema/beans" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:aop="https://www.springframework.org/schema/aop" xmlns:tx="https://www.springframework.org/schema/tx" xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.0.xsd https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/TestDB" /> <property name="username" value="pankaj" /> <property name="password" value="pankaj123" /> </bean> <!-- Définition du bean Hibernate 4 SessionFactory --> <bean id="hibernate4AnnotatedSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="annotatedClasses"> <list> <value>com.journaldev.model.Person</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.current_session_context_class">thread</prop> <prop key="hibernate.show_sql">false</prop> </props> </property> </bean> <bean id="personDAO" class="com.journaldev.dao.PersonDAOImpl"> <property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" /> </bean> </beans>
Pour Hibernate 4, nous devons utiliser
org.springframework.orm.hibernate4.LocalSessionFactoryBean
pour le bean SessionFactory, Spring ORM a fusionné les deux classes pour Hibernate 3 et il n’y a maintenant qu’une seule classe, ce qui est bon pour éviter la confusion. Toutes les autres configurations sont les mêmes qu’auparavant.
C’est tout, notre projet a été migré avec succès vers Hibernate 4, n’est-ce pas propre ? Il suffit de changer la classe SpringHibernateMain
pour utiliser spring4.xml
pour la configuration des beans et tout fonctionnera bien, vous obtiendrez le même résultat qu’auparavant. Vous pouvez télécharger le projet final à partir du lien ci-dessous et jouer avec d’autres configurations pour en apprendre davantage.
Source:
https://www.digitalocean.com/community/tutorials/spring-hibernate-integration-example-tutorial