Friday, December 18, 2009

Spring, JSF & Hibernate Integration - Part III

This tutorial mentions Step-by-Step instructions for developing Spring, JSF & Hibernate integrated application. It totally has three parts:

I. Creating simple Spring application
II. Creating application involving Spring and JSF
III. Creating application involving Spring, JSF and Hibernate

The current tutorial deals with the third part of creating application involving Spring, JSF & Hibernate.

The final netbeans project after completing Part III of the current tutorial has been uploaded here. Because of size limitations the third party jars inside the lib folder has been deleted in the uploaded zip file.

Requirements :: Netbeans 6.7.1 with Java 6 installed

Steps
=====
Ensure that you have gone through the first and second part of tutorial.

You can continue the below steps starting with the netbeans project available here which is obtained after performing steps in Part II of the tutorial

27. Create links database table and insert some sample records into it. The DDL for the links table is given below: -

CREATE TABLE LINKS (
LINK_ID INT NOT NULL,
TITLE VARCHAR(150),
HTTP_LINK VARCHAR(100),
DESCRIPTION VARCHAR(3000)
);

After table creation, insert some records into it.

28. Create linkedlinks.hbm.xml file determining the mapping between Link POJO domain object and database table LINKS. Create a folder with name resources under the java sources root folder and place the xml file inside resources folder

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.linkedlinks.domain.Link" table="LINKS">
<id name="linkId" column="LINK_ID">
<generator class="increment"/>
</id>
<property name="httpLink">
<column name="HTTP_LINK"/>
</property>
<property name="title">
<column name="TITLE"/>
</property>
<property name="description">
<column name="DESCRIPTION"/>
</property>
</class>
</hibernate-mapping>

The generator class for linkId attribute is set as increment. This takes care of automatically populating the link id property of newly created link to next available ID.

29. Create a class implementing LinkDao which uses hibernate to persist the data. Name it as HibernateLinkDao.java under the repository package.

class java


30. Create a property file links.properties under WEB-INF folder containing details of jdbc database settings.

jdbc.driverClassName=JDBC_DRIVER_QUALIFIED_CLASS_NAME
jdbc.url=JDBC_CONNECTION_URL
jdbc.username=USERNAME
jdbc.password=YOUR_PASSWORD

Ensure that you have included the jar containing the above driver class in your project libraries.

31. Create bean definitions with ids propertyConfigurer and myDataSource in applicationContext.xml as given below.

<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/links.properties" />
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />

32. Define session factory and hibernate template beans in applicationContext.xml

<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingResources">
<list>
<value>./resources/linkedlinks.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>hibernate.dialect=org.hibernate.dialect.HSQLDialect</value>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="mySessionFactory"/>
</property>
</bean>


33. Create a new bean definition on HibernateLinkDao class in applicationContext.xml file. Also set the previously defined hibernateTemplate bean as the value of hibernateTemplate property of this bean. Change the linkDao property reference bean value of myService bean from linkDao to myHibenrateLinkDao. Now the service uses the hibernate dao class instead of SimulateDao class.

<bean id="myHibernateLinkDao" class="com.linkedlinks.repository.HibernateLinkDao">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate" />
</property>
</bean>
<bean id="myService" class="com.linkedlinks.service.LinksServiceImpl">
<property name="linkDao">
<ref bean="myHibernateLinkDao" />
</property>
</bean>

34. Run createlink.jsp and pages will be displayed accordingly. The data will be retreived from database tables and any new link creations will be persisted in the DB.

This completes the tutorial of integrating Spring, JSF & Hibernate technologies.

Thursday, December 17, 2009

Spring, JSF & Hibernate Integration - Part II

This tutorial mentions Step-by-Step instructions for developing Spring, JSF & Hibernate integrated application. It totally has three parts:

I. Creating simple Spring application
II. Creating application involving Spring and JSF
III. Creating application involving Spring, JSF and Hibernate

The current tutorial deals with the second part of creating application having Spring and JSF.

The final netbeans project after completing Part II of the current tutorial has been uploaded here. Because of size limitations the third party jars inside the lib folder has been deleted in the uploaded zip file.

Requirements :: Netbeans 6.7.1 with Java 6 installed

Steps
=====
Ensure that you have gone through the first part of tutorial here.

You can continue the below steps starting with the netbeans project available here which is obtained after performing steps in Part I of the tutorial

14. Create a LinkBean.java class which is used to maintain components state in JSF UI components. It accesses LinksService implementation class for business functions.

package com.linkedlinks.bean;

import com.linkedlinks.domain.Link;
import com.linkedlinks.service.LinksService;
import java.util.List;

/**
*
* @author harish
*/
public class LinkBean {
private LinksService linksService;
private String title;
private String httpLink;
private String description;

public Long getTotalLinksCount(){
return linksService.getTotalLinksCount();
}

public String createLink(){
linksService.createLink(title, httpLink,description);
return "createLinkSuccess";
}

public List<Link> getLinksList() {
List<Link> list = linksService.getLinks();
return list;
}

public void saveLink(Link link){
linksService.updateLink(link);
}

public void setLinksService(LinksService linksService) {
this.linksService = linksService;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getHttpLink() {
return httpLink;
}

public void setHttpLink(String httpLink) {
this.httpLink = httpLink;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}
}

15. Delete welcomeJSF.jsp file inside Web Pages which was auto-generated.

16. Configure faces-config.xml such that it tells JSF to pick up managed bean definitions from spring beans definition file. For that add the below entry to faces-config.xml

<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>

17. Define bean definition for LinkBean.java class in applicationContext.xml so that the JSF can access it. Add below entry to applicationContext.xml

<bean id="myBean" class="com.linkedlinks.bean.LinkBean">
<property name="linksService">
<ref bean="myService" />
</property>
</bean>

18. Add below entry of RequestContextListener to web.xml so that spring can understand the meaning of request scope in the bean definition.

<listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

19. Set the scope as request for myBean definition in applicationContext.xml

<bean id="myBean" class="com.linkedlinks.bean.LinkBean" scope="request">
<property name="linksService">
<ref bean="myService" />
</property>
</bean>

20. Create a jsf page - linkslist.jsp inside page folder under Web Pages to list all the links using dataTable jsf UI component.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<f:view>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>JSP Page</title>
</head>
<body>
<h:form id="f1">
<h:commandLink value="Create Link" action="createlink" />
<h:dataTable width="90%" id="dt1" value="#{myBean.linksList}" var="link"
border="1">
<h:column>
<f:facet name="header"><h:outputText value="Title"/></f:facet>
<h:outputLink value="#{link.httpLink}">
<h:outputText value="#{link.title}"/>
</h:outputLink>
</h:column>
<h:column>
<f:facet name="header"><h:outputText value="Description"/></f:facet>
<h:outputText value="#{link.description}"/>
</h:column>
</h:dataTable>
</h:form>
</body>
</html>
</f:view>

21. Run linkslist.jsp file from netbeans. It will display a table displaying the details of the five links. This data is retreived from SimulateDao class

22. Create another jsf page - createlink.jsp having a form to create a new link. In the action attribute of commandButton, invoke the createLink method of myBean.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<f:view>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Create Link Page</title>
</head>
<body>
<h:form>
<h:commandLink value="Links list" action="linkslist" />
<h:panelGrid id="panel" columns="2" border="1">
<f:facet name="header">
<h:outputText value="Create New Link"/>
</f:facet>
<h:outputLabel for="title" value="Title" />
<h:inputText id="title" value="#{myBean.title}" />
<h:outputLabel for="httpLink" value="Http Link" />
<h:inputText id="httpLink" value="#{myBean.httpLink}" />
<h:outputLabel for="description" value="Description" />
<h:inputText id="description" value="#{myBean.description}" />
<f:facet name="footer">
<h:panelGroup style="display:block; text-align:center">
<h:commandButton id="submit" value="Create"
action="#{myBean.createLink}" />
</h:panelGroup>
</f:facet>
</h:panelGrid>
</h:form>
</body>
</html>
</f:view>

23. Add below navigation rule in faces-config.xml. It says that if we get createLinkSuccess outcome from createlink.jsp file, then navigate to linkslist.jsp page.

<navigation-rule>
<from-view-id>/page/createlink.jsp</from-view-id>
<navigation-case>
<from-outcome>createLinkSuccess</from-outcome>
<to-view-id>/page/linkslist.jsp</to-view-id>
</navigation-case>
</navigation-rule>

24. Now when we run createlink.jsp, enter values and press Create button, it redirects to linkslist.jsp page listing the newly added link in the table.

25. Similarly add links in both createlink.jsp & linkslist.jsp to navigate between these two pages.
Add below entry above panelGrid definition in createlink.jsp

<h:commandLink value="Links list" action="linkslist" />

Add below entry above dataTable definition in linkslist.jsp

<h:commandLink value="Create Link" action="createlink" />

Change the navigation rules in faces-config.xml as below to enable page navigation between create and list link pages.

<navigation-rule>
<from-view-id>/page/createlink.jsp</from-view-id>
<navigation-case>
<from-outcome>createLinkSuccess</from-outcome>
<to-view-id>/page/linkslist.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>linkslist</from-outcome>
<to-view-id>/page/linkslist.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/page/linkslist.jsp</from-view-id>
<navigation-case>
<from-outcome>createlink</from-outcome>
<to-view-id>/page/createlink.jsp</to-view-id>
</navigation-case>
</navigation-rule>

Swith over to PageFlow view of faces-config.xml which shows the connections between create and list pages.

26. Re-run createlink.jsp file and the links are displayed at top in both create and list link pages for navigation.

This completes integration of JSF with Spring. To contiue further for integrating Hibernate with Spring & JSF, go through part III of the tutorial here.

Wednesday, December 16, 2009

Spring, JSF & Hibernate Integration - Part I

This tutorial mentions Step-by-Step instructions for developing Spring, JSF & Hibernate integrated application. It totally has three parts:

I. Creating simple Spring application
II. Creating application involving Spring and JSF
III. Creating application involving Spring, JSF and Hibernate

The current tutorial deals with the first part of creating application having only Spring. After the application is developed, a sample console program has been created which shows the application in run.

The final netbeans project after completing Part I of the current tutorial has been uploaded here. Because of size limitations the third party jars inside the lib folder has been deleted in the uploaded zip file.

Requirements :: Netbeans 6.7.1 with Java 6 installed

Steps
====
1. Create a java web project using Java EE 5 technology with the Java Server Faces & Hibernate frameworks included. Spring Web MVC is not required as we will be using JSF for page navigation.

2. Import and add SpringFramework 2.5 library. Spring MVC library is NOT required

3. create applicationContext.xml in WEB-INF folder with following content

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
</beans>

4. Delete hibernate.cfg.xml inside default source package, as we will be configuring hibernate in spring applicationContext.xml file

5. Add below entries to web.xml

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

6. Create Link.java POJO in domain package with getters & setters for its attributes. Also override the toString() method which returns a string containing link details.

package com.linkedlinks.domain;

/**
*
* @author harish
*/
public class Link {
private Long linkId;
private String httpLink;
private String title;
private String description;

public Link(){

}

public Link(String title,String httpLink,String description){
this.title = title;
this.httpLink = httpLink;
this.description = description;
}

public Link(Long id,String title,String httpLink,String description){
this.linkId = id;
this.title = title;
this.httpLink = httpLink;
this.description = description;
}
/**
* @return the httpLink
*/
public String getHttpLink() {
return httpLink;
}

/**
* @param httpLink the httpLink to set
*/
public void setHttpLink(String httpLink) {
this.httpLink = httpLink;
}

/**
* @return the title
*/
public String getTitle() {
return title;
}

/**
* @param title the title to set
*/
public void setTitle(String title) {
this.title = title;
}

/**
* @return the Description
*/
public String getDescription() {
return description;
}

/**
* @param Description the Description to set
*/
public void setDescription(String Description) {
this.description = Description;
}

/**
* @return the linkId
*/
public Long getLinkId() {
return linkId;
}

/**
* @param linkId the linkId to set
*/
public void setLinkId(Long linkId) {
this.linkId = linkId;
}

public String toString(){
return linkId+" "+title+" "+httpLink+" "+description;
}

}


7. Create LinkDao.java interface in repository package declaring required DAO methods in it.

package com.linkedlinks.repository;

import com.linkedlinks.domain.Link;
import java.util.List;

/**
*
* @author harish
*/
public interface LinkDao {
public List<Link> getLinks();
public void addLink(Link link);
public void removeLink(Link link);
public void updateLink(Link link);
public Link getLink(Long linkId);
public Long getTotalLinksCount();
}


8. Create SimulateDao.java implementing LinkDao which returns a sample implementation of DAO.

package com.linkedlinks.repository;

import com.linkedlinks.domain.Link;
import java.util.ArrayList;
import java.util.List;

/**
*
* @author harish
*/
public class SimulateDao implements LinkDao {

private List<Link> links;
static Long linkSequence = 6L;

public SimulateDao() {
links = new ArrayList<Link>();
Long[] linkids = {1L, 2L, 3L, 4L, 5L};
String[] httpLinks = {"http://link1", "http://link2", "http://link3", "http://link4", "http://link5"};
String[] titles = {"title1", "title2", "title3", "title4", "title5"};
String[] descs = {"desc1", "desc2", "desc3", "desc4", "desc5"};
for (int i = 0; i < linkids.length; i++) {
Link link = new Link(linkids[i], titles[i], httpLinks[i], descs[i]);
links.add(link);
}
}

public List<Link> getLinks() {
return links;
}

public void addLink(Link link) {
if (link.getLinkId() == null || link.getLinkId() == 0) {
link.setLinkId(linkSequence++);
}
links.add(link);
}

public void removeLink(Link link) {
links.remove(link);
}

public void updateLink(Link link) {
removeLink(link);
addLink(link);
}

public Link getLink(Long linkId) {
for (int i = 0; i < links.size(); i++) {
Link link = links.get(i);
if (linkId.equals(link.getLinkId())) {
return link;
}
}
return null;
}

public Long getTotalLinksCount() {
return (long) links.size();
}
}


9. Create LinksService.java interface declaring the business requirement methods.

package com.linkedlinks.service;

import com.linkedlinks.domain.Link;
import java.util.List;

/**
*
* @author harish
*/
public interface LinksService {
public Long getTotalLinksCount();
public List<Link> getLinks();
public Link createLink(String title,String desc,String httpLink);
public void removeLink(Link link);
public void updateLink(Link link);
}


10. Create LinksServiceImpl.java implementing LinksService which accesses any of the DAO implementation classes for data access or storage

package com.linkedlinks.service;

import com.linkedlinks.domain.Link;
import com.linkedlinks.repository.LinkDao;
import java.util.List;

/**
*
* @author harish
*/
public class LinksServiceImpl implements LinksService {
private LinkDao linkDao;

public LinksServiceImpl(){
}

public void updateLink(Link link){
linkDao.updateLink(link);
}

public Long getTotalLinksCount(){
return linkDao.getTotalLinksCount();
}

public List<Link> getLinks(){
return linkDao.getLinks();
}

public Link createLink(String title,String httpLink,String desc){
Link link = new Link(title,httpLink,desc);
linkDao.addLink(link);
return link;
}

public void removeLink(Link link){
linkDao.removeLink(link);
}

public void setLinkDao(LinkDao linkDao) {
this.linkDao = linkDao;
}
}


11. Now configure the beans in applicationContext.xml file to set proper dependency injection.

<bean id="myDao" class="com.linkedlinks.repository.SimulateDao" />
<bean id="myService" class="com.linkedlinks.service.LinksServiceImpl">
<property name="linkDao">
<ref bean="myDao" />
</property>
</bean>


12. Create a sample console client applicatin which uses LinksService to perform business functions. Create it under client package - ConsoleClient.java

package com.linkedlinks.client;

import com.linkedlinks.domain.Link;
import com.linkedlinks.service.LinksService;
import java.util.List;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

/**
*
* @author harish
*/
public class ConsoleClient {

private LinksService linksService;

public static void main(String[] args) {
new ConsoleClient().demo();
}

public void demo() {
setupBeans();
displayAllLinks(linksService.getLinks());

Link link6 = linksService.createLink("title6","http://link6","desc6");
Link link7 = linksService.createLink("title7","http://link7", "desc7");

System.out.println("Two links added.. Total links count = " + linksService.getTotalLinksCount());
linksService.removeLink(link6);
link7.setDescription("Big Desc 7");
linksService.updateLink(link7);
System.out.println("link 6 removed.. link 7 description updated..");
displayAllLinks(linksService.getLinks());
}

private void setupBeans() {
Resource res = new FileSystemResource("web/WEB-INF/applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(res);
LinksService myService = (LinksService) factory.getBean("myService");
setLinksService(myService);
}

private void displayAllLinks(List<Link> links) {
System.out.println("All links details");
for (Link link : links) {
System.out.println(link);
}
}

public LinksService getLinksService() {
return linksService;
}

public void setLinksService(LinksService linksService) {
this.linksService = linksService;
}
}


13. Now you can see the output by running the console client.

This completes the spring part of the tutorial. To contiue further for integrating JSF with Spring, go through part II of the tutorial here.