lundi 14 avril 2014

Spring, Hibernate and JSF2 Integration

In this tutorial, we'll learn how to integrate the Hibernate framework in our Spring application. We'll create a SessionFactory as a Spring singleton and use that in our DAO class to work with the database, and show data with jsf.
Spring 3.2.2
Hibernate 4.1
JSF2

P.S In this example, we are using MySQL database and deploy to Tomcat 7 web container.
1. Database Script
CREATE TABLE `student` 
  ( 
     `studentid` BIGINT(20) UNSIGNED NOT NULL auto_increment, 
     `firstname`  VARCHAR(50) NOT NULL, 
     `lastname`   VARCHAR(50) NOT NULL, 
     PRIMARY KEY (`student_id`) 
  ) engine=innodb auto_increment=17 DEFAULT charset=utf8; 
INSERT INTO student (studentid, firstname, lastname) 
VALUES      (1, 'firstname1', 'lastname1');
INSERT INTO student (studentid, firstname, lastname) 
VALUES      (2, 'firstname2', 'lastname2');

2. Project Structure


















3. Entity Definition : 
package com.model; 
import java.io.Serializable; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
@Entity 
public class Student implements Serializable{ 
    @Id 
    @GeneratedValue 
    private long studentid; 
    
    @Column 
    private String firstname; 
    
    @Column 
    private String lastname; 
    
    public Student(){ 
         
    } 
    public long getStudentid() { 
        return studentid; 
    } 
    public void setStudentid(long studentid) { 
        this.studentid = studentid; 
    } 
    public String getFirstname() { 
        return firstname; 
    } 
    public void setFirstname(String firstname) { 
        this.firstname = firstname; 
    } 
    public String getLastname() { 
        return lastname; 
    } 
    public void setLastname(String lastname) { 
        this.lastname = lastname; 
    }     
}
4. Create DAO :
      4.1.Interface :
package com.dao; 
import java.util.List; 
import com.model.Student; 
public interface StudentDao { 
    public void add(Student student); 
    public List<Student> findAll(); 
}
      4.2.Implementation :
package com.dao.impl; 
import java.util.List; 
import org.hibernate.SessionFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.Transactional; 
import com.dao.StudentDao; 
import com.model.Student; 
@Transactional 
@Repository 
public class StudentDaoImpl implements StudentDao{ 
    @Autowired 
    private SessionFactory sessionFactory; 
    @Override 
    public void add(Student student) { 
        sessionFactory.getCurrentSession().persist(student); 
    } 
    @Override 
    public List<Student> findAll() { 
        return sessionFactory.getCurrentSession().createQuery("from Student ").list();
    } 
}
5. Create Service :
      5.1.Interface :
package com.service;  import java.util.List;  import com.model.Student;  public interface StudentService {       public void add(Student student);       public List<Student> getAll(); 
      5.2.Implementation :
package com.service.impl;  import java.util.List;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.stereotype.Service;  import com.dao.StudentDao;  import com.model.Student;  import com.service.StudentService;  @Service  public class StudentServiceImpl implements StudentService {      @Autowired      private StudentDao studentDao;      @Override      public void add(Student student) {          studentDao.add(student);      }      @Override      public List<Student> getAll() {          return studentDao.findAll();      }  }

6. Spring and Hibernate configuration (file application-context.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:security="http://www.springframework.org/schema/security" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd   http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
   <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
      <property name="user" value="root" />
      <property name="driverClass" value="org.gjt.mm.mysql.Driver" />
      <property name="jdbcUrl" value="jdbc:mysql://localhost/tutorial" />
      <property name="password" value="root" />
      <property name="maxStatementsPerConnection" value="0" />
      <property name="maxAdministrativeTaskTime" value="0" />
      <property name="maxConnectionAge" value="0" />
      <property name="maxIdleTime" value="0" />
      <property name="maxIdleTimeExcessConnections" value="0" />
      <property name="maxPoolSize" value="0" />
      <property name="maxStatements" value="0" />
   </bean>
   <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
      <property name="dataSource" ref="dataSource" />
      <property name="packagesToScan" value="com.model" />
      <property name="hibernateProperties">
         <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.c3p0.acquire_increment">1</prop>
            <prop key="hibernate.c3p0.minPoolSize">10</prop>
            <prop key="hibernate.c3p0.maxPoolSize">200</prop>
            <prop key="hibernate.c3p0.timeout">1800</prop>
            <prop key="hibernate.c3p0.max_statement">0</prop>
         </props>
      </property>
   </bean>
   <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
      <property name="sessionFactory" ref="sessionFactory" />
   </bean>
   <tx:annotation-driven transaction-manager="transactionManager" />
   <context:annotation-config />
   <context:component-scan base-package="com" />
</beans>
7. JSF
JSF managed bean to call spring's service to get or to add records from database
package com.bean; 
import java.util.List; 
import javax.faces.bean.ManagedBean; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Scope; 
import org.springframework.stereotype.Component; 
import com.model.Student; 
import com.service.StudentService; 
@ManagedBean(name="studentBean"
@Scope 
@Component 
public class StudentBean { 
    @Autowired 
    private StudentService studentService; 
    private Student student; 

    public StudentBean(){ 
        student = new Student(); 
    } 
    public void addStudent(){ 
        studentService.add(student); 
        student = new Student(); 
    } 
    public List<Student> getStudentList(){ 
        return studentService.getAll(); 
    } 
    public Student getStudent() { 
        return student; 
    } 
    public void setStudent(Student student) { 
        this.student = student; 
    }
    public StudentService getStudentService() { 
        return studentService; 
    } 
    public void setStudentService(StudentService studentService) { 
        this.studentService = studentService; 
    } 
}
A JSF page to display existing student records via h:dataTable and a few text components to allow user to insert new student record into database. (file index.xhtml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"   
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:f="http://java.sun.com/jsf/core"
   >
   <h:head>
      <h:outputStylesheet library="css" name="table-style.css"  />
   </h:head>
   <h:body>
      <h1>Spring Hibernate JSF Example</h1>
      <h:dataTable value="#{studentBean.getStudentList()}" var="s">
         <h:column>
            <f:facet name="header">
               Student ID
            </f:facet>
            #{s.studentid}
         </h:column>
         <h:column>
            <f:facet name="header">
               First Name
            </f:facet>
            #{s.firstname}
         </h:column>
         <h:column>
            <f:facet name="header">
               Last Name
            </f:facet>
            #{s.lastname}
         </h:column>
      </h:dataTable>
      <h2>Add New Student</h2>
      <h:form>
         <h:panelGrid columns="3">
            First Name : 
            <h:inputText id="fname" value="#{studentBean.student.firstname}" 
               size="50" required="true"
               label="First Name" >
            </h:inputText>
            <h:message for="fname" style="color:red" />
            Last Name : 
            <h:inputText id="lname" value="#{studentBean.student.lastname}" 
               size="50" required="true"
               label="Last Name" >
            </h:inputText>
            <h:message for="lname" style="color:red" />
         </h:panelGrid>
         <h:commandButton value="Submit" action="#{studentBean.addStudent()}" />
      </h:form>
   </h:body>
</html>
8. Spring + JSF

file faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
   xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
   version="2.0">
   <application>
      <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
   </application>
</faces-config>
file web.xml
<?xml version="1.0" encoding="ASCII"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
   <display-name></display-name>
   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
         /WEB-INF/application-context.xml
      </param-value>
   </context-param>
   <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>
   <listener>
      <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
   </listener>
   <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.jsf</url-pattern>
   </servlet-mapping>
   <welcome-file-list>
      <welcome-file>index.jsf</welcome-file>
   </welcome-file-list>
</web-app>

Download this example
You have a question ? post it here http://developerfirm.com/

4 commentaires:

  1. Bonjour

    j'ai suivie votre tutorial mot à mot mais lorsque j'aarive a l'exécution il m'affiche deux erreurs la premiere concerne la methode StudentBean.getStudentList() et la deuxième StudentBean.addStudent alors j'ai decidé de supprime la partie d'aafichage de la liste des students et de laisseé que l'enregistrement de nov student mais encore il m'affiche la méme erreur java.lang.NullPointerException: StudentBean.addStudent().
    Voulez-vous m'aider à resoudre cet erreur et merci d'avance

    RépondreSupprimer
  2. Transaction attributes have to be in Service layer rather than Dao layer, IMHO.

    RépondreSupprimer
  3. You dont have annontate the jsf manage bean with both @managebean and @component.. either one of them is enough.

    RépondreSupprimer
  4. Merhaba Raouf.
    Proje için teşekkür ederim güzel bir çalışma olmuş. Eline Sağlık.
    Fakat yaptığığm kayıtlar veritabanına yansımıyor ve veritabanına manuel eklediğim bilgilerde okunmuyor. Hata mesajıda almıyorum. Sebebi ne olabilir.
    Eclipse Neon ve Tomcat7 kullanıyorum. Cevabın için şimdiden teşekkürler. Kolay Gelsin.

    RépondreSupprimer