Welcome to the Spring Primefaces and Hibernate Integration example. Integration between frameworks is a complex mission and mostly it needs a lot of time to achieve. We’ve discussed a Primefaces, Spring and Hibernate frameworks in a separate tutorials, but this time we will show you how can integrate all of them to create a layered (tiered) application.
Spring Primefaces Hibernate
Layered (tiered) application is a popular design that most of the enterprise applications are aligned with. In which:
- Primefaces framework will be used for handling all UI concerns and verify client’s inputs.
- Hibernate framework will be used for communicating your own persistence store that probably is a MySQL database.
- Spring framework will be used to glue between all of these frameworks.
This tutorial intended for implementing a layered application using all of these listed frameworks.
Spring Primefaces Hibernate Required Tools
Before getting started delve into, let’s see the required tools that you would need for:
- Eclipse Kepler 4.3.
- Hibernate 3.x.
- Spring 4.x.
- Primefaces 5.x.
- JDK 1.6+.
- MySQL 5.x.
Primefaces Spring Hibernate Project Structure
Our final project structure will look like below image, we will go through each of the components one by one.
Create Database Employee Table
MySQL database would be used for retaining all of employees instances/records. Used Employee Table looks like below:
Also, find below its SQL create-script:
1 2 3 4 5 6 7 8 9 |
CREATE TABLE `employee` ( `EMP_ID` int(11) NOT NULL AUTO_INCREMENT, `EMP_NAME` varchar(45) DEFAULT NULL, `EMP_HIRE_DATE` datetime DEFAULT NULL, `EMP_SALARY` decimal(11,4) DEFAULT NULL, PRIMARY KEY (`EMP_ID`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; |
Create Employee Model Bean
After we created an Employee Table, it’s a proper time to get a look at how Employee class would look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package com.journaldev.hibernate.data; import java.util.Date; public class Employee { private long employeeId; private String employeeName; private Date employeeHireDate; private double employeeSalary; public long getEmployeeId() { return employeeId; } public void setEmployeeId(long employeeId) { this.employeeId = employeeId; } public String getEmployeeName() { return employeeName; } public void setEmployeeName(String employeeName) { this.employeeName = employeeName; } public Date getEmployeeHireDate() { return employeeHireDate; } public void setEmployeeHireDate(Date employeeHireDate) { this.employeeHireDate = employeeHireDate; } public double getEmployeeSalary() { return employeeSalary; } public void setEmployeeSalary(double employeeSalary) { this.employeeSalary = employeeSalary; } } |
Spring Primefaces Hibernate Maven Dependencies
Maven is a build tool, it’s used mainly for managing project dependencies. So no need for downloading JARs and appending them into your project as you did normally. MySQL JDBC driver, hibernate core, Spring core framework, Primefaces and many libraries that we need for Spring Hibernate Primefaces integration. Our final pom.xml file looks like below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.journaldev</groupId> <artifactId>Primefaces-Hibernate-Spring-Integration-Sample</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>Primefaces-Hibernate-Spring-Integration-Sample Maven Webapp</name> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <url>https://maven.apache.org</url> <repositories> <repository> <id>prime-repo</id> <name>PrimeFaces Maven Repository</name> <url>https://repository.primefaces.org</url> <layout>default</layout> </repository> </repositories> <dependencies> <!-- Servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!-- Faces Implementation --> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-impl</artifactId> <version>2.2.4</version> </dependency> <!-- Faces Library --> <dependency> <groupId>com.sun.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.2.4</version> </dependency> <!-- Primefaces Version 5 --> <dependency> <groupId>org.primefaces</groupId> <artifactId>primefaces</artifactId> <version>5.0</version> </dependency> <!-- JSP Library --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <!-- JSTL Library --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.1.2</version> </dependency> <!-- Primefaces Theme Library --> <dependency> <groupId>org.primefaces.themes</groupId> <artifactId>blitzer</artifactId> <version>1.0.10</version> </dependency> <!-- Hibernate library --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.6.10.Final</version> </dependency> <!-- MySQL driver connector library --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.31</version> </dependency> <!-- Spring ORM --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.0.3.RELEASE</version> </dependency> <!-- Spring Web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.3.RELEASE</version> </dependency> <!-- Required By Hibernate --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.1.GA</version> </dependency> </dependencies> </project> |
Spring Primefaces – Hibernate Configuration
Hibernate is a standard Object Relational Mapping (ORM) solution, it’s used for mapping your object domain into relational tabular formula. Hibernate configuration process require below steps:
- Specify all relevant database information like driver, JDBC URL, hibernate dialect and hibernate session context in a hibernate configuration file, mainly using hibernate.cfg.xml. Dialect will be used by hibernate implementation itself for make sure the execution of mapping process is done effectively. This file should be located under project’s src/main/resources folder.
- Specify hibernate’s mapping file. Mapping file will contains all of mapping information, like objects-tables, attributes-columns and associations-relations, domain-classes.hbm.xml file is mainly used for this purpose. This file should be located under project’s src/main/resources folder so that it’s in the classpath of the application.
- It’s important to say that some of modifications would be required when we’re going to use Spring.
hibernate.cfg.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "https://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/journaldev</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!-- SQL dialect --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Specify session context --> <property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property> <!-- Show SQL --> <property name="hibernate.show_sql">true</property> <!-- Referring Mapping File --> <mapping resource="domain-classes.hbm.xml"/> </session-factory> </hibernate-configuration> |
domain-classes.hbm.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "https://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping> <class name="com.journaldev.hibernate.data.Employee" table="employee"> <id name="employeeId" column="EMP_ID" type="long"> <generator class="native" /> </id> <property name="employeeName" column="EMP_NAME" type="string"/> <property name="employeeHireDate" column="EMP_HIRE_DATE" type="date"/> <property name="employeeSalary" column="EMP_SALARY" type="double"/> </class> </hibernate-mapping> |
Test our Hibernate Application
Till now, we’ve created an Eclipse Web project configured with required dependencies, created database Employee Table and created hibernate framework accompanies.
Before going far away with Spring integration and developing a Primefaces UI form, let’s see how can we use a simple Java Application for getting Employee instance saved against our own database. Given Java Application would help us identifying the benefits we’ll get especially when it comes to use a Spring framework later on.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com.journaldev; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import com.journaldev.hibernate.data.Employee; public class Main { public static void main(String [] args){ // Create a configuration instance Configuration configuration = new Configuration(); // Provide configuration file configuration.configure("hibernate.cfg.xml"); // Build a SessionFactory SessionFactory factory = configuration.buildSessionFactory(new StandardServiceRegistryBuilder().configure().build()); // Get current session, current session is already associated with Thread Session session = factory.getCurrentSession(); // Begin transaction, if you would like save your instances, your calling of save must be associated with a transaction session.getTransaction().begin(); // Create employee Employee emp = new Employee(); emp.setEmployeeName("Peter Jousha"); emp.setEmployeeSalary(2000); emp.setEmployeeHireDate(new Date()); // Save session.save(emp); // Commit, calling of commit will cause save an instance of employee session.getTransaction().commit(); } } |
Here’s detailed clarifications for the above code:
- Hibernate requires a defined context for make your acquired session affected. Standard Java Application context can be achieved by providing hibernate’s attribute hibernate.current_session_context_class. Value of org.hibernate.context.internal.ThreadLocalSessionContext will be binded the context to the current executed thread. That’s mean, if you’ve invoked any type of CRUD operations against session object within an active Transaction, they will be executing into your own database once the Transaction has committed. In our case, an new employee instance has been saved. If you’ve used hibernate 3, this property should be thread instead of using ThreadLocalSessionContext.
- Hibernate 4 is used for Testing purpose, this version of hibernate isn’t applicable when it comes to integrate with Spring 4. To integrate with Spring 4, you’ve requested to use Hibernate 3.
- Using of latest version of hibernate requires you to use
StandardServiceRegistryBuilder
to build SessionFactory.
Setting Up Spring
Spring is a comprehensive framework, it’s used mainly for Inversion of Control (IoC) which consider the more general category of the well-known concept Dependency Injection.
However, a provided simple Java Application keep you capable of getting your Employee instances saved against your own database, but typically, this isn’t the way that most of applications use to configure their own hibernate persistence layer.
Using of Spring will help you avoiding all creating and associating objects stuffs. Creating required objects, associating others are mainly a Spring job. Following are Spring context configuration file, updated hibernate configuration, updated Maven pom.xml and our deployment descriptor file. Let’s see how can we configure all of these to make a proper use of Spring.
applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<?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:tx="https://www.springframework.org/schema/tx" xmlns:context="https://www.springframework.org/schema/context" xmlns:aop="https://www.springframework.org/schema/aop" xmlns:util="https://www.springframework.org/schema/util" 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.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.2.xsd https://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> <!-- Enable Spring Annotation Configuration --> <context:annotation-config /> <!-- Scan for all of Spring components such as Spring Service --> <context:component-scan base-package="com.journaldev.spring.service"></context:component-scan> <!-- Create Data Source bean --> <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/journaldev" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> <!-- Define SessionFactory bean --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mappingResources"> <list> <value>domain-classes.hbm.xml</value> </list> </property> <property name="configLocation"> <value>classpath:hibernate.cfg.xml</value> </property> </bean> <!-- Transaction Manager --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!-- Detect @Transactional Annotation --> <tx:annotation-driven transaction-manager="transactionManager" /> </beans> |
hibernate.cfg.xml
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "https://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- SQL dialect --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> </session-factory> </hibernate-configuration> |
web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xmlns:web="https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5" metadata-complete="true"> <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>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <context-param> <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>com.sun.faces.config.ConfigureListener</listener-class> </listener> </web-app> |
Here’s detailed explanation for the code given above:
- We’ve created a SessionFactory by instantiating a Spring Bean called sessionFactory. Instantiating of SessionFactory does require passing an instant of data source instance, passing mapping files (domain-classes.hbm.xml as is), passing all required Hibernate properties via using of hibernate.cfg.xml. As you’ve noticed, hibernate.cfg.xml doesn’t contain database information, cause it’s defined instantly – Data Source Bean – and no need for hibernate session context, cause it’s enriched by Apache Tomcat. Even Apache Tomact isn’t a managed server, but it contains facilities that make help create a contextual session.
- Transaction Manager will help you eliminate using a snippet of code like session.getTransaction().begin() and commit(). @Transactional annotation will be used alternatively. That’s mean, executing of any Spring Service’s methods annotated with @Transactional will be done in a Transnational manner. In case you’ve called a CRUD operation against your session within a Transnational scope like session.save(), it will be executing directly into your own database at the end of called method. That’s called Transaction Demarcation.
- You can define your own Spring Services by using @Component. That will be scanned automatically.
- A new libraries are added into our pom.xml maven dependencies file, common-dbcp and javassist are required by hibernate 3. If you’ve noticed, these libraries aren’t required for Hibernate 4.
- It’s mandatory to add Spring context loader listener for your web.xml file. This listener required an applicationContext.xml to be defined underneath of WEB-INF/ folder. This is the default location and name for Spring configuration context file. In case you would to change its location and name you must add below snippet of code provided with required path.
Configure non-default Spring Context Location:
1 2 3 4 5 6 |
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/SpringContext.xml</param-value> </context-param> |
NOTE: If you are looking for Spring 4 and Hibernate 4 integration, we need to make some small changes in the Spring Bean configuration file, you can get more details about that at Spring Hibernate Integration Example.
Spring EmployeeService
In a layered application like what we’re doing here, all of business operations must be achieved by services. Spring provides you ability to define your own services that would contain your own business rules. EmployeeService would contain the required business for create an Employee.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.journaldev.spring.service; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import com.journaldev.hibernate.data.Employee; @Component public class EmployeeService { @Autowired private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Transactional public void register(Employee emp){ // Acquire session Session session = sessionFactory.getCurrentSession(); // Save employee, saving behavior get done in a transactional manner session.save(emp); } } |
Here’s detailed explanation for the above code:
- EmployeeService is a Spring service, @Component annotation is used for defining Spring Service. By default, Spring will scan your mentioned package(s) for locating your service based on context:component-scanTag.
- @Autowired will help you get required instances injected. That’s Dependency Injection or IoC (Inversion of Control) concept. It’s important concept, it means that instead of allowing the developer controlling the process of creating instances and making required associations as well. It makes all of these creation and association in behind seen. That is an incredible power of Spring. @Autowired is used for injecting one instance of SessionFactory, if you’re worry about performance issue, you can define your SessionFactory bean as a singleton scope. For complete information about autowiring, read Spring autowiring example.
- @Transactional annotation is used for Transaction Demarcation purpose. Transaction demarcation is used for associating your contextual session with an active Transaction. That will cause a CRUD operation to get executed against your own database. You should go through Spring Declarative Transaction Management Example.
Primefaces Managed Bean – RegisterEmployee
Managed Bean is a JSF facility, and it’s used for handling all required User Interface validations. In a layered application, Managed Bean is used for invoking Business services. You may be wondering once you know that it’s applicable for you to inject EmployeeService Spring bean into your own Managed Bean. That becomes true if you’re used @ManagedProperty annotation.
faces-config.xml
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="https://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd" version="2.2"> <application> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> </application> </faces-config> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package com.journaldev.prime.faces.beans; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.SessionScoped; import javax.faces.context.FacesContext; import com.journaldev.hibernate.data.Employee; import com.journaldev.spring.service.EmployeeService; @ManagedBean @SessionScoped public class RegisterEmployee { @ManagedProperty("#{employeeService}") private EmployeeService employeeService; private Employee employee = new Employee(); public EmployeeService getEmployeeService() { return employeeService; } public void setEmployeeService(EmployeeService employeeService) { this.employeeService = employeeService; } public Employee getEmployee() { return employee; } public void setEmployee(Employee employee) { this.employee = employee; } public String register() { // Calling Business Service employeeService.register(employee); // Add message FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("The Employee "+this.employee.getEmployeeName()+" Is Registered Successfully")); return ""; } } |
Here’s detailed explanation for the above code:
- RegisterEmployee Managed Bean is developed with using of
@ManagedProperty
annotation that will help you get a Spring EmployeeService instance injected. That association won’t be applicable if you don’t provide a special faces-config.xml file that contains a newly added Spring’s el-resolver. - Primefaces UI form will help you gather all required information about registered employee.
- Register action will ask EmployeeService saving given employee instance.
Primefaces – Register Form
index.xhtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<html xmlns="https://www.w3.org/1999/xhtml" xmlns:ui="https://java.sun.com/jsf/facelets" xmlns:h="https://java.sun.com/jsf/html" xmlns:f="https://java.sun.com/jsf/core" xmlns:p="https://primefaces.org/ui"> <h:head> <script name="jquery/jquery.js" library="primefaces"></script> <title>Register Employee</title> </h:head> <h:form> <p:growl id="messages"></p:growl> <p:panelGrid columns="2"> <p:outputLabel value="Enter Employee Name:"></p:outputLabel> <p:inputText value="#{registerEmployee.employee.employeeName}"></p:inputText> <p:outputLabel value="Enter Employee Hire Date:"></p:outputLabel> <p:calendar value="#{registerEmployee.employee.employeeHireDate}"></p:calendar> <p:outputLabel value="Enter Employee Salary:"></p:outputLabel> <p:inputText value="#{registerEmployee.employee.employeeSalary}"></p:inputText> </p:panelGrid> <p:commandButton value="Register" action="#{registerEmployee.register}" update="messages"></p:commandButton> </h:form> </html> |
Spring Primefaces Hibernate Example Summary
Hibernate integration with Spring and Primefaces is a popular development task. This tutorial guides you thoroughly to get Hibernate integrated with Spring and Primefaces that would lead you into getting an employee persisted against your database. Some technical details are mentioned intentionally. Contribute us by commenting below and find the source code for downloading purpose.