Bienvenue dans le didacticiel d’exemple Hibernate Tomcat JNDI DataSource. Nous avons déjà vu comment utiliser l’outil Hibernate ORM dans une application Java autonome, aujourd’hui nous apprendrons comment utiliser Hibernate avec DataSource dans le conteneur de servlets Tomcat. Utiliser Hibernate dans une application web est très simple, il suffit de configurer les propriétés du `DataSource` dans le fichier de configuration Hibernate. Tout d’abord, nous devons configurer une base de données de test et un JNDI DataSource dans le conteneur Tomcat.
Exemple de configuration de la source de données Hibernate JNDI
I am using MySQL for my example, below script is executed to create a simple table and insert some values into it. employee.sql
CREATE TABLE `Employee` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`role` varchar(20) DEFAULT NULL,
`insert_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
INSERT INTO `Employee` (`id`, `name`, `role`, `insert_time`)
VALUES
(3, 'Pankaj', 'CEO', now());
INSERT INTO `Employee` (`id`, `name`, `role`, `insert_time`)
VALUES
(14, 'David', 'Developer', now());
Le nom du schéma de la base de données est TestDB.
Configuration de Tomcat JNDI DataSource
Pour configurer le conteneur Tomcat afin d’initialiser le DataSource, nous devons apporter certaines modifications aux fichiers server.xml et context.xml de Tomcat. `server.xml`
<Resource name="jdbc/MyLocalDB"
global="jdbc/MyLocalDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/TestDB"
username="pankaj"
password="pankaj123"
maxActive="100"
maxIdle="20"
minIdle="5"
maxWait="10000"/>
Ajoutez la ressource ci-dessus à l’élément `GlobalNamingResources` du fichier `server.xml`. `context.xml`
<ResourceLink name="jdbc/MyLocalDB"
global="jdbc/MyLocalDB"
auth="Container"
type="javax.sql.DataSource" />
Ajoutez le ResourceLink
ci-dessus dans le fichier context.xml, il est nécessaire pour que les applications puissent accéder à la ressource JNDI avec le nom jdbc/MyLocalDB
. Redémarrez simplement le serveur, vous ne devriez voir aucune erreur dans les journaux du serveur Tomcat. S’il y a des configurations incorrectes, telles que le mot de passe erroné, vous obtiendrez l’exception correspondante dans le journal du serveur. Assurez-vous également que le fichier jar du pilote MySQL se trouve dans le répertoire lib de Tomcat, sinon Tomcat ne pourra pas établir de connexion avec la base de données et vous obtiendrez une ClassNotFoundException
dans les journaux. Maintenant, notre configuration JNDI du serveur de base de données et de Tomcat est prête, passons à la création de notre application web en utilisant Hibernate.
Exemple de projet web dynamique avec Hibernate et DataSource
Créez un projet web dynamique dans Eclipse, puis configurez-le en tant que projet Maven. La structure finale de notre projet sera comme indiqué dans l’image ci-dessous. Notez que j’utilise Tomcat-7 pour le déploiement de mon projet, et je l’ai ajouté au chemin de construction, afin de ne pas avoir à ajouter séparément les dépendances de l’API Servlet dans notre projet. Tomcat-7 prend en charge les spécifications Servlet 3, et nous utiliserons des annotations pour créer nos servlets. Si vous n’êtes pas familier avec les annotations Servlet 3, consultez le Tutoriel Servlet pour les débutants. Examions chacun des composants un par un.
Dépendances Maven pour Hibernate
Notre fichier pom.xml final ressemble à ce qui suit.
<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>HibernateDataSource</groupId>
<artifactId>HibernateDataSource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.5.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>
I am using Hibernate latest version 4.3.5.Final, hibernate-core
dependency is added for Hibernate. mysql-connector-java
dependency is added because we are using MySQL database, although scope is provided because it’s already part of the tomcat container libraries. Even if we don’t add MySQL driver dependencies, our project will compile and run fine. However it’s better to include it so that if someone will look into the project dependencies, it will be clear that we are using MySQL database.
Configuration de la source de données Hibernate
Notre fichier de configuration Hibernate avec la source de données ressemble à ce qui suit. hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.datasource">java:comp/env/jdbc/MyLocalDB</property>
<property name="hibernate.current_session_context_class">thread</property>
<!-- Mapping with model class containing annotations -->
<mapping class="com.journaldev.servlet.hibernate.model.Employee"/>
</session-factory>
</hibernate-configuration>
La propriété hibernate.connection.datasource
est utilisée pour fournir le nom de la source de données qui sera utilisée par Hibernate pour les opérations de base de données.
Exemple de modèle de source de données Hibernate
Comme vous pouvez le voir dans le fichier de configuration Hibernate, nous utilisons des annotations dans notre classe modèle Employee. Notre bean modèle ressemble à ceci. Employee.java
package com.journaldev.servlet.hibernate.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@Table(name="Employee",
uniqueConstraints={@UniqueConstraint(columnNames={"ID"})})
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID", nullable=false, unique=true, length=11)
private int id;
@Column(name="NAME", length=20, nullable=true)
private String name;
@Column(name="ROLE", length=20, nullable=true)
private String role;
@Column(name="insert_time", nullable=true)
private Date insertTime;
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 getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Date getInsertTime() {
return insertTime;
}
public void setInsertTime(Date insertTime) {
this.insertTime = insertTime;
}
}
Le bean modèle est le même que celui que nous avons utilisé dans le Tutoriel pour débutants Hibernate, vous devriez le vérifier si vous avez des confusions liées à l’une des annotations utilisées.
Écouteur de Servlet JNDI Tomcat de la source de données Hibernate
Puisque nous devons initialiser la SessionFactory
Hibernate car nous pouvons l’utiliser dans l’application et aussi lorsque l’application web est détruite, nous devons détruire la SessionFactory. Le meilleur endroit pour le faire est donc dans une implémentation de ServletContextListener
. HibernateSessionFactoryListener.java
package com.journaldev.servlet.hibernate.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.jboss.logging.Logger;
@WebListener
public class HibernateSessionFactoryListener implements ServletContextListener {
public final Logger logger = Logger.getLogger(HibernateSessionFactoryListener.class);
public void contextDestroyed(ServletContextEvent servletContextEvent) {
SessionFactory sessionFactory = (SessionFactory) servletContextEvent.getServletContext().getAttribute("SessionFactory");
if(sessionFactory != null && !sessionFactory.isClosed()){
logger.info("Closing sessionFactory");
sessionFactory.close();
}
logger.info("Released Hibernate sessionFactory resource");
}
public void contextInitialized(ServletContextEvent servletContextEvent) {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
logger.info("Hibernate Configuration created successfully");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
logger.info("ServiceRegistry created successfully");
SessionFactory sessionFactory = configuration
.buildSessionFactory(serviceRegistry);
logger.info("SessionFactory created successfully");
servletContextEvent.getServletContext().setAttribute("SessionFactory", sessionFactory);
logger.info("Hibernate SessionFactory Configured successfully");
}
}
Si vous n’êtes pas familier avec les auditeurs de servlets, veuillez lire Tutoriel sur les auditeurs de servlets.
Implémentation de l’exemple de servlet Hibernate Tomcat JNDI
Écrivons un servlet simple où nous passerons l’identifiant de l’employé en tant que paramètre de requête et il affichera les informations de l’employé à partir de la base de données, évidemment nous utiliserons Hibernate pour interroger la base de données et obtenir les informations de l’employé. GetEmployeeByID.java
package com.journaldev.servlet.hibernate;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.jboss.logging.Logger;
import com.journaldev.servlet.hibernate.model.Employee;
@WebServlet("/GetEmployeeByID")
public class GetEmployeeByID extends HttpServlet {
private static final long serialVersionUID = 1L;
public final Logger logger = Logger.getLogger(GetEmployeeByID.class);
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int empId = Integer.parseInt(request.getParameter("empId"));
logger.info("Request Param empId="+empId);
SessionFactory sessionFactory = (SessionFactory) request.getServletContext().getAttribute("SessionFactory");
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Employee emp = (Employee) session.get(Employee.class, empId);
tx.commit();
PrintWriter out = response.getWriter();
response.setContentType("text/html");
if(emp != null){
out.print("<html><body><h2>Employee Details</h2>");
out.print("<table border=\"1\" cellspacing=10 cellpadding=5>");
out.print("<th>Employee ID</th>");
out.print("<th>Employee Name</th>");
out.print("<th>Employee Role</th>");
out.print("<tr>");
out.print("<td>" + empId + "</td>");
out.print("<td>" + emp.getName() + "</td>");
out.print("<td>" + emp.getRole() + "</td>");
out.print("</tr>");
out.print("</table></body><br/>");
out.print("</html>");
}else{
out.print("<html><body><h2>No Employee Found with ID="+empId+"</h2></body></html>");
}
}
}
C’est une classe de servlet très simple, j’utilise l’annotation @WebServlet
pour fournir le motif URI pour cela.
Application d’exemple de test Hibernate DataSource Tomcat JNDI
Notre application est maintenant prête, il suffit d’exporter le fichier war et de le déployer dans le conteneur Tomcat. Voici quelques captures d’écran lorsque nous invoquons notre servlet d’application.
Remarquez que je passe le paramètre de requête empId dans la chaîne de requête de l’URL de la requête. Vous verrez également les journaux générés par notre application dans les journaux du serveur.
May 08, 2014 8:14:16 PM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: hibernate.cfg.xml
May 08, 2014 8:14:16 PM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: hibernate.cfg.xml
May 08, 2014 8:14:16 PM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
May 08, 2014 8:14:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: Hibernate Configuration created successfully
May 08, 2014 8:14:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: ServiceRegistry created successfully
May 08, 2014 8:14:16 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
May 08, 2014 8:14:17 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
May 08, 2014 8:14:17 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
May 08, 2014 8:14:17 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
May 08, 2014 8:14:17 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: SessionFactory created successfully
May 08, 2014 8:14:17 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextInitialized
INFO: Hibernate SessionFactory Configured successfully
May 08, 2014 8:14:32 PM com.journaldev.servlet.hibernate.GetEmployeeByID doGet
INFO: Request Param empId=3
May 08, 2014 8:15:22 PM com.journaldev.servlet.hibernate.GetEmployeeByID doGet
INFO: Request Param empId=3
Si vous désinstallez l’application ou arrêtez le serveur, vous verrez les journaux du serveur pour la destruction de la SessionFactory.
May 08, 2014 11:31:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextDestroyed
INFO: Closing sessionFactory
May 08, 2014 11:31:16 PM com.journaldev.servlet.hibernate.listener.HibernateSessionFactoryListener contextDestroyed
INFO: Released Hibernate sessionFactory resource
C’est tout pour l’exemple de DataSource Hibernate pour le conteneur Tomcat, j’espère que c’est facile à comprendre et à mettre en œuvre. Téléchargez le projet exemple à partir du lien ci-dessous et jouez avec pour en apprendre davantage.
Source:
https://www.digitalocean.com/community/tutorials/hibernate-tomcat-jndi-datasource-example-tutorial