Wednesday, October 30, 2013

Step by step configuration of Hibernate, Spring MVC, Primefaces

So, you have decided to use Spring, Hibernate and Primefaces in your application. I am very much fond of each one of them cause, all of them very easy to use and open source. I use all of them in my own application.
But, the first time I tried to configure them in my application, I had nightmare. The most tough part was to configure Hibernate with Spring and to find how to use Spring beans in Managed Beans. But now my application is stable and development has become easy for me now.
So, I thought of sharing the knowledge to configure the application to use all of them.
I will use HSQL as DB for this post. I assume that you are capable of configuring your DB in the configuration files. Because, you are reading this post means, you are an advanced Java Developer.

Prerequisite
1.     You have knowledge on Spring, Hibernate and JSF and know the basics of setting them up individually
2.     Knowledge of Eclipse IDE or Maven or any other build tool
3.     Working database
4.     Hibernate 4 and Spring 4 (For another pair of these, generally these configuration needs a little change in the session factory configuration, which you can figure out in ease)
5.     Primefaces (3 or 4) and Spring(3 or 4)
This pair can have any combination. Choose any. Spring versioons are compatible with Primefaces versions.
Configuration
 I will go step by step for the configurations.


1. Mention the required libraries in your build - Required library list is huge cause Spring, Hibernate and Primefaces depend on different libraries. So please be careful otherwise you will get many exceptions. There are total 28 dependencies in total.
§  antlr-2.7.7.jar
§  commons-logging-1.1.1.jar
§  dom4j-1.6.1.jar
§  el-impl-2.2.1-b05.jar
§  hibernate-commons-annotations-4.0.5.Final.jar
§  hibernate-core-4.3.7.Final.jar
§  hibernate-jpa-2.1-api-1.0.0.Final.jar
§  hsqldb.jar
§  jandex-1.1.0.Final.jar
§  javassist-3.18.1-GA.jar
§  jboss-logging-3.1.3.GA.jar
§  jboss-logging-annotations-1.2.0.Beta1.jar
§  jboss-transaction-api_1.2_spec-1.0.0.Final.jar
§  jsf-api-2.2.8-02.jar
§  jsf-impl-2.2.8-02.jar
§  jstl-1.2.jar
§  primefaces-4.0.jar
§  spring-aop-4.1.3.RELEASE.jar
§  spring-beans-4.1.3.RELEASE.jar
§  spring-context-4.1.3.RELEASE.jar
§  spring-context-support-4.1.3.RELEASE.jar
§  spring-core-4.1.3.RELEASE.jar
§  spring-expression-4.1.3.RELEASE.jar
§  spring-jdbc-4.1.3.RELEASE.jar
§  spring-orm-4.1.3.RELEASE.jar
§  spring-tx-4.1.3.RELEASE.jar
§  spring-web-4.1.3.RELEASE.jar
§  spring-webmvc-4.1.3.RELEASE.jarWith all these dependencies, WebContent/WEB-INF/lib looks like

2.       Setup JSF for your application
Dependency declaration is complete. The next step is to setup Faces for your application.
In your web.xml mention faces servlet and the extensions you want to map with JSF and run your server. It should be working.
If not, then delete the web.xml and retry. Here is one sample for ease.




 <?xml version="1.0" encoding="UTF-8"?>  
 <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/web-app_2_5.xsd"  
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
      id="WebApp_ID" version="2.5">  
      <display-name>PrimeFaces Web Application</display-name>  
      <!-- Change to "Production" when you are ready to deploy -->  
      <context-param>  
           <param-name>javax.faces.PROJECT_STAGE</param-name>  
           <param-value>Development</param-value>  
      </context-param>  
      <!-- Welcome page -->  
      <welcome-file-list>  
           <welcome-file>faces/index.xhtml</welcome-file>  
      </welcome-file-list>  
      <!-- JSF mapping -->  
      <servlet>  
           <servlet-name>Faces Servlet</servlet-name>  
           <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>  
           <load-on-startup>1</load-on-startup>  
      </servlet>  
      <!-- Map these files with JSF -->  
      <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>*.jsf</url-pattern>  
      </servlet-mapping>  
      <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>  
 </web-app>  

3.       Add Spring MVC to Faces
Now, add Spring MVC to your faces application. You have to include  Spring context file as context-param with param name contextConfigLocation and RequestContextListener and ContextLoaderListener as your application listener.
So, basically you have to add three more tags in your web.xml.
Now, it’s time to write faces-config.xml. Here you mention SpringBeanFacesELResolver as the EL Resolver for your faces application.
After adding these, restart the server to check if configuration is working.


 <context-param>  
     <param-name>contextConfigLocation</param-name>  
     <param-value>  
       /WEB-INF/resources/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>  

This is the faces-config file
 <?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>  

4.       Add Hibernate to Spring
In your context file, DriverManagerDataSource as data source, hibernate4.LocalSessionFactoryBean as sessionFactory and use this in your DAO classes. Add POJO, hibernate configurations and mappings etc in the project.
Again restart the server and it is in complete configuration.


 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans  
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
      <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">  
           <property name="driverClassName" value="org.hsqldb.jdbc.JDBCDriver">  
           <property name="url" value="jdbc:hsqldb:hsql://localhost:1521/opt/db">  
           <property name="username" value="SA">  
           <property name="password" value="">  
      </property></property></property></property></bean>  
      <bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" id="sessionFactory">  
           <property name="dataSource" ref="dataSource">  
           <property name="configLocation" value="classpath:hibernate.cfg.xml">  
      </property></property></bean>  
      <bean class="dao.EmployeeDaoImpl" id="employeeDAO">  
           <property name="sessionFactory" ref="sessionFactory">  
      </property></bean>  
      <bean class="service.EmployeeService" id="service">  
           <property name="dao" ref="employeeDAO">  
      </property></bean>  
 </beans>  

Hibernate configuration
 <?xml version="1.0" encoding="utf-8"?>  
 <!DOCTYPE hibernate-configuration SYSTEM   
 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">  
 <hibernate-configuration>  
      <session-factory>  
           <property name="hibernate.dialect">  
                org.hibernate.dialect.HSQLDialect  
           </property>  
           <property name="hibernate.connection.driver_class">  
                org.hsqldb.jdbc.JDBCDriver  
           </property>  
           <!-- Assume test is the database name -->  
           <property name="hibernate.connection.url">  
                jdbc:hsqldb:hsql://localhost:1521/opt/db  
           </property>  
           <property name="hibernate.connection.username">  
                SA  
           </property>  
           <property name="hibernate.connection.password">  
           </property>  
           <!-- List of XML mapping files -->  
           <mapping resource="resources/Employee.hbm.xml" />  
      </session-factory>  
 </hibernate-configuration>  

Mapping
 <?xml version="1.0" encoding="utf-8"?>  
 <!DOCTYPE hibernate-mapping PUBLIC   
  "-//Hibernate/Hibernate Mapping DTD//EN"  
  "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">   
 <hibernate-mapping>  
   <class name="bean.Employee" table="EMPLOYEE">  
    <meta attribute="class-description">  
      This class contains the employee detail.   
    </meta>  
    <id name="sapCode" type="int" column="sap_code">  
      <generator class="native"/>  
    </id>  
    <property name="firstName" column="first_name" type="string"/>  
    <property name="lastName" column="last_name" type="string"/>  
    <property name="middleName" column="middle_name" type="string"/>  
   </class>  
 </hibernate-mapping>  

5.   Retrieve Spring beans in Managed Beans
All the setup is complete. To retrieve Spring beans, in your Managed beans, use @ManagedProperty on attributes.

 package managedbeans;  
 import javax.faces.bean.ManagedBean;  
 import javax.faces.bean.ManagedProperty;  
 import service.EmployeeService;  
 @ManagedBean(name = "editor")  
 public class EditorBean {  
      @ManagedProperty(name = "service", value = "#{service}")  
      private EmployeeService service;  
      private String value = "Editor";  
      /**  
       * @return the value  
       */  
      public String getValue() {  
           return value;  
      }  
      /**  
       * @param value  
       *      the value to set  
       */  
      public void setValue(String value) {  
           this.value = value;  
      }  
      /**  
       * @return the service  
       */  
      public EmployeeService getService() {  
           return service;  
      }  
      /**  
       * @param service  
       *      the service to set  
       */  
      public void setService(EmployeeService service) {  
           this.service = service;  
      }  
      public void save() {  
           System.out.println("Using service");  
           System.out.println(getValue());  
           System.out.println(service.getEmployees());  
      }  
 }  


Enjoy the development with these components. They are really cool stuffs.

I've complete websites built on top of these three only. They really are helpful for faster development, better maintainability, less coding, good looking GUI. You are free to take a look in the below locations,

https://assistant-palash90.rhcloud.com/req-resp.asst

https://temperatureconverter-palash90.rhcloud.com/


That's it. If anything breaks, in between, you can post comment, I will check and revert back.

If this helped you out, you can share this in your network as well. Sharing is caring...


Next
Palash Kanti Kundu

No comments:

Post a Comment