You are on page 1of 83

WEB TECHNOLOGY

UNIT- V

MVC Architecture
In this section, you will get an overview of MVC architecture. The MVC
architectural pattern has existed for a long time in software engineering. All
most all the languages use MVC with slight variation, but conceptually it
remains the same.

Let's understand the MVC architecture in ASP.NET.

MVC stands for Model, View and Controller. MVC separates application into
three components - Model, View and Controller.

Model: Model represents shape of the data and business logic. It maintains
the data of the application. Model objects retrieve and store model state in a
database.

Model is a data and business logic.

View: View is a user interface. View display data using model to the user
and also enables them to modify the data.

View is a User Interface.

Controller: Controller handles the user request. Typically, user interact with
View, which in-turn raises appropriate URL request, this request will be
handled by a controller. The controller renders the appropriate view with the
model data as a response.

Controller is a request handler.

The following figure illustrates the interaction between Model, View and
Controller.
MVC Architecture
The following figure illustrates the flow of the user's request in ASP.NET
MVC.

Request/Re
sponse in MVC Architecture
As per the above figure, when the user enters a URL in the browser, it goes
to the server and calls appropriate controller. Then, the Controller uses the
appropriate View and Model and creates the response and sends it back to
the user. We will see the details of the interaction in the next few sections.

Points to Remember :
1. MVC stands for Model, View and Controller.
2. Model is responsible for maintaining application data and business
logic.

3. View is a user interface of the application, which displays the data.

4. Controller handles user's requests and renders appropriate View with


Model data.
Java Server Faces
What is JSF?
JavaServer Faces (JSF) is a MVC web framework that simplifies the construction of
User Interfaces (UI) for server-based applications using reusable UI components in a
page. JSF provides a facility to connect UI widgets with data sources and to server-
side event handlers. The JSF specification defines a set of standard UI components
and provides an Application Programming Interface (API) for developing components.
JSF enables the reuse and extension of the existing standard UI components.

Benefits
JSF reduces the effort in creating and maintaining applications, which will run on a
Java application server and will render application UI on to a target client. JSF
facilitates Web application development by −

 Providing reusable UI components


 Making easy data transfer between UI components

 Managing UI state across multiple server requests

 Enabling implementation of custom components

 Wiring client-side event to server-side application code

JSF UI Component Model


JSF provides the developers with the capability to create Web application from
collections of UI components that can render themselves in different ways for multiple
client types (for example - HTML browser, wireless, or WAP device).
JSF provides −
 Core library
 A set of base UI components - standard HTML input elements
 Extension of the base UI components to create additional UI component libraries or to
extend existing components
 Multiple rendering capabilities that enable JSF UI components to render themselves
differently depending on the client types
JSF technology is a framework for developing, building server-side User Interface
Components and using them in a web application. JSF technology is based on the
Model View Controller (MVC) architecture for separating logic from presentation.
What is MVC Design Pattern?
MVC design pattern designs an application using three separate modules −

S.No Module & Description

1 Model
Carries Data and login

2 View
Shows User Interface

Controller
3
Handles processing of an application.

The purpose of MVC design pattern is to separate model and presentation enabling
developers to focus on their core skills and collaborate more clearly.
Web designers have to concentrate only on view layer rather than model and controller
layer. Developers can change the code for model and typically need not change view
layer. Controllers are used to process user actions. In this process, layer model and
views may be changed.

JSF Architecture
JSF application is similar to any other Java technology-based web application; it runs
in a Java servlet container, and contains −
 JavaBeans components as models containing application-specific functionality and data
 A custom tag library for representing event handlers and validators
 A custom tag library for rendering UI components
 UI components represented as stateful objects on the server
 Server-side helper classes
 Validators, event handlers, and navigation handlers
 Application configuration resource file for configuring application resources
There are controllers which can be used to perform user actions. UI can be created by
web page authors and the business logic can be utilized by managed beans.
JSF provides several mechanisms for rendering an individual component. It is upto the
web page designer to pick the desired representation, and the application developer
doesn't need to know which mechanism was used to render a JSF UI component.

JSF - Life Cycle


JSF application life cycle consists of six phases which are as follows −

 Restore view phase


 Apply request values phase; process events

 Process validations phase; process events

 Update model values phase; process events

 Invoke application phase; process events

 Render response phase


The six phases show the order in which JSF processes a form. The list shows the
phases in their likely order of execution with event processing at each phase.

Phase 1: Restore view


JSF begins the restore view phase as soon as a link or a button is clicked and JSF
receives a request.
During this phase, JSF builds the view, wires event handlers and validators to UI
components and saves the view in the FacesContext instance. The FacesContext
instance will now contain all the information required to process a request.

Phase 2: Apply request values


After the component tree is created/restored, each component in the component tree
uses the decode method to extract its new value from the request parameters.
Component stores this value. If the conversion fails, an error message is generated
and queued on FacesContext. This message will be displayed during the render
response phase, along with any validation errors.
If any decode methods event listeners called renderResponse on the current
FacesContext instance, the JSF moves to the render response phase.

Phase 3: Process validation


During this phase, JSF processes all validators registered on the component tree. It
examines the component attribute rules for the validation and compares these rules to
the local value stored for the component.
If the local value is invalid, JSF adds an error message to the FacesContext instance,
and the life cycle advances to the render response phase and displays the same page
again with the error message.
Phase 4: Update model values
After the JSF checks that the data is valid, it walks over the component tree and sets
the corresponding server-side object properties to the components' local values. JSF
will update the bean properties corresponding to the input component's value attribute.
If any updateModels methods called renderResponse on the current FacesContext
instance, JSF moves to the render response phase.

Phase 5: Invoke application


During this phase, JSF handles any application-level events, such as submitting a
form/linking to another page.

Phase 6: Render response


During this phase, JSF asks container/application server to render the page if the
application is using JSP pages. For initial request, the components represented on the
page will be added to the component tree as JSP container executes the page. If this is
not an initial request, the component tree is already built so components need not be
added again. In either case, the components will render themselves as the JSP
container/Application server traverses the tags in the page.
After the content of the view is rendered, the response state is saved so that
subsequent requests can access it and it is available to the restore view phase.

JSF - Basic Tags

JSF provides a standard HTML tag library. These tags get rendered into corresponding
html output.
For these tags you need to use the following namespaces of URI in html node.
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:h = "http://java.sun.com/jsf/html">
Following are the important Basic Tags in JSF 2.0.

S.No Tag & Description

h:inputText
1
Renders a HTML input of type="text", text box.
h:inputSecret
2
Renders a HTML input of type="password", text box.

h:inputTextarea
3
Renders a HTML textarea field.

h:inputHidden
4
Renders a HTML input of type="hidden".

h:selectBooleanCheckbox
5
Renders a single HTML check box.

h:selectManyCheckbox
6
Renders a group of HTML check boxes.

h:selectOneRadio
7
Renders a single HTML radio button.

h:selectOneListbox
8
Renders a HTML single list box.

h:selectManyListbox
9
Renders a HTML multiple list box.

h:selectOneMenu
10
Renders a HTML combo box.

h:outputText
11
Renders a HTML text.

h:outputFormat
12
Renders a HTML text. It accepts parameters.

h:graphicImage
13
Renders an image.

14 h:outputStylesheet
Includes a CSS style sheet in HTML output.

h:outputScript
15
Includes a script in HTML output.

h:commandButton
16
Renders a HTML input of type="submit" button.

h:Link
17
Renders a HTML anchor.

h:commandLink
18
Renders a HTML anchor.

h:outputLink
19
Renders a HTML anchor.

h:panelGrid
20
Renders an HTML Table in form of grid.

h:message
21
Renders message for a JSF UI Component.

h:messages
22
Renders all message for JSF UI Components.

f:param
23
Pass parameters to JSF UI Component.

f:attribute
24
Pass attribute to a JSF UI Component.

f:setPropertyActionListener
25
Sets value of a managed bean's property.
JSF - Facelets Tags
JSF provides special tags to create common layout for a web application called
facelets tags. These tags provide flexibility to manage common parts of multiple pages
at one place.
For these tags, you need to use the following namespaces of URI in html node.
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:ui = "http://java.sun.com/jsf/facelets">
Following are important Facelets Tags in JSF 2.0.

S.No Tag & Description

Templates

We'll demonstrate how to use templates using the following tags

1  <ui:insert>
 <ui:define>

 <ui:include>

 <ui:composition>

Parameters
We'll demonstrate how to pass parameters to a template file using the following tag
2
 <ui:param>

Custom
3
We'll demonstrate how to create custom tags

Remove
4
We'll demonstrate capability to remove JSF code from generated HTML page

JSF - Convertor Tags


JSF provides inbuilt convertors to convert its UI component's data to object used in a
managed bean and vice versa. For example, these tags can convert a text into date
object and can validate the format of input as well.
For these tags, you need to use the following namespaces of URI in html node.
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:f = "http://java.sun.com/jsf/core">

Following are important Convertor Tags in JSF 2.0 −

S.No Tag & Description

f:convertNumber
1
Converts a String into a Number of desired format

f:convertDateTime
2
Converts a String into a Date of desired format

Custom Convertor
3
Creating a custom convertor

JSF - Validator Tags


JSF provides inbuilt validators to validate its UI components. These tags can validate
the length of the field, the type of input which can be a custom object.
For these tags you need to use the following namespaces of URI in html node.
<html
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:f = "http://java.sun.com/jsf/core">
Following are important Validator Tags in JSF 2.0−

S.No Tag & Description

f:validateLength
1
Validates the length of a string

f:validateLongRange
2
Validates the range of a numeric value

f:validateDoubleRange
3
Validates the range of a float value
f:validateRegex
4
Validates JSF component with a given regular expression

Custom Validator
5
Creates a custom validator

JSF - Composite Components


JSF provides the developers with a powerful capability to define their own custom
components, which can be used to render custom contents.

Define Custom Component


Defining a custom component in JSF is a two-step process.

Step Description

1a Create a resources folder.


Create a xhtml file in resources folder with a composite namespace.

Use composite tags composite:interface, composite:attribute and composite:implementation, to define


1b content of the composite component. Use cc.attrs in composite:implementation to get variable defined
using composite:attribute in composite:interface.

Step 1a: Create Custom Component : loginComponent.xhtml


Create a folder tutorialspoint in resources folder and create a file
loginComponent.xhtml in it.
Use composite namespace in html header.
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:h = "http://java.sun.com/jsf/html"
xmlns:f = "http://java.sun.com/jsf/core"
xmlns:composite = "http://java.sun.com/jsf/composite">
...
</html>
Step 1b: Use Composite Tags : loginComponent.xhtml
Following table describes the use of composite tags.

S.No Tag & Description

1 composite:interface
Declares configurable values to be used in composite:implementation.

2 composite:attribute
Configuration values are declared using this tag.

composite:implementation
3
Declares JSF component. Can access the configurable values defined in composite:interface using
#{cc.attrs.attribute-name} expression.

<composite:interface>
<composite:attribute name = "usernameLabel" />
<composite:attribute name = "usernameValue" />
</composite:interface>

<composite:implementation>
<h:form>
#{cc.attrs.usernameLabel} :
<h:inputText id = "username" value = "#{cc.attrs.usernameValue}"
/>
</h:form>

Use Custom Component


Using a custom component in JSF is a simple process.

Step Description

Create a xhtml file and use custom component's namespace. Namespace will
2a the http://java.sun.com/jsf/<folder-name> where folder-name is folder in resources directory containing the
custom component

2b Use the custom component as normal JSF tags


Step 2a: Use Custom Namespace: home.xhtml
<html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:h = "http://java.sun.com/jsf/html"
xmlns:ui = "http://java.sun.com/jsf/facelets">
xmlns:tp = "http://java.sun.com/jsf/composite/tutorialspoint">

Step 2b: Use Custom Tag: home.xhtml and Pass Values


<h:form>
<tp:loginComponent
usernameLabel = "Enter User Name: "
usernameValue = "#{userData.name}" />
</h:form>

Example Application
Let us create a test JSF application to test the custom component in JSF.

Step Description

Create a project with a name helloworld under a package com.tutorialspoint.test as explained in the JSF -
1
First Application chapter.

2 Create resources folder under src → main folder.

3 Create tutorialspoint folder under src → main → resources folder.

4 Create loginComponent.xhtml file under src → main → resources → tutorialspoint folder.

5 Modify UserData.java file as explained below.

6 Modify home.xhtml as explained below. Keep the rest of the files unchanged.

7 Compile and run the application to make sure the business logic is working as per the requirements.

8 Finally, build the application in the form of war file and deploy it in Apache Tomcat Webserver.

9 Launch your web application using appropriate URL as explained below in the last step.
loginComponent.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"
xmlns:composite = "http://java.sun.com/jsf/composite">

<composite:interface>
<composite:attribute name = "usernameLabel" />
<composite:attribute name = "usernameValue" />
<composite:attribute name = "passwordLabel" />
<composite:attribute name = "passwordValue" />
<composite:attribute name = "loginButtonLabel" />
<composite:attribute name = "loginButtonAction"
method-signature = "java.lang.String login()" />
</composite:interface>

<composite:implementation>
<h:form>
<h:message for = "loginPanel" style = "color:red;" />

<h:panelGrid columns = "2" id = "loginPanel">


#{cc.attrs.usernameLabel} :
<h:inputText id = "username" value =
"#{cc.attrs.usernameValue}" />
#{cc.attrs.passwordLabel} :
<h:inputSecret id = "password" value =
"#{cc.attrs.passwordValue}" />
</h:panelGrid>

<h:commandButton action = "#{cc.attrs.loginButtonAction}"


value = "#{cc.attrs.loginButtonLabel}"/>
</h:form>
</composite:implementation>
</html>

UserData.java
package com.tutorialspoint.test;

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name = "userData", eager = true)


@SessionScoped
public class UserData implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String password;

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

public String getPassword() {


return password;
}

public void setPassword(String password) {


this.password = password;
}

public String login() {


return "result";
}
}

home.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"
xmlns:tp = "http://java.sun.com/jsf/composite/tutorialspoint">

<h:head>
<title>JSF tutorial</title>
</h:head>

<h:body>
<h2>Custom Component Example</h2>

<h:form>
<tp:loginComponent
usernameLabel = "Enter User Name: "
usernameValue = "#{userData.name}"
passwordLabel = "Enter Password: "
passwordValue = "#{userData.password}"
loginButtonLabel = "Login"
loginButtonAction = "#{userData.login}" />
</h:form>
</h:body>
</html>

Once you are ready with all the changes done, let us compile and run the application
as we did in JSF - First Application chapter. If everything is fine with your application,
this will produce the following result.

Struts: Working principle of Struts


The basic purpose of the Java Servlets in struts is to handle requests made by
the client or by web browsers. In struts JavaServerPages (JSP) are used to
design the dynamic web pages. In struts, servlets helps to route request which
has been made by the web browsers to the appropriate ServerPage. The use of
servlet as a router helps to make the web applications easier to design, create,
and maintain. Struts is purely based on the Model- View- Contoller (MVC) design
pattern. It is one of the best and most well developed design patterns in use. By
using the MVC architecture we break the processing in three sections named
Model, the View, and the Controller. Below we are describing the working of
struts.

1. As we all are well aware of the fact that each application we develop has a
deployment descriptor i.e. WEB-INF/web.xml. This is the file which the
container reads. This file has all the configuration information which we
have defined for our web application. The configuration information
includes the index file, the default welcome page, the mapping of our
servlets including path and the extension name, any init parameters,
information related to the context elements.
In the file WEB-INF/web.xml of struts application we need to configure the
Struts ActionServlet which handles all the request made by the web
browsers to a given mapping. ActionServlet is the central component of
the Struts controller. This servlet extends the HttpServlet. This servlet
basically performs two important things. First is : When the container gets
start, it reads the Struts Configuration files and loads it into memory in
the init() method. You will know more about the Struts Configuration files
below. Second point is: It intercepts the HTTP request in
the doGet() and doPost() method and handles it appropriately.

2. In struts application we have another xml file which is a Struts


configuration file named as struts.config.xml. The name of this file can be
changed. The name of the struts configuration file can be configured in the
web.xml file. This file is placed under the WEB-INF directory of the web
application. It is an XML document that describes all or part of Struts
application. This file has all the information about many types of Struts
resources and configures their interaction. This file is used to associate
paths with the controller components of your application., known as Action
classes like <action path ="/login" type = "LoginAction">. This tag tells the
Struts ActionServlet that whenever the incoming request
is http://myhost/myapp/login.do, then it must invoke the controller
component LoginAction. Above, you can see that we have written .do in
the URL. This mapping is done to tell the web application that whenever a
request is received with the .do extension then it should be appended to
the URL.

3. For each action we also have to configure Struts with the names of the
resulting pages that will be shown as a result of that action. In our
application there can be more than one view which depends on the result
of an action. One can be for a success and the other for the failure. If the
result action is "success" then the action tells the ActionServlet that the
action has been successfully accomplished or vice- versa. The struts
knows how to forward the specific page to the concerned destination. The
model which we want to use is entirely to you, the model is called from
within the controller components.

4. Action can also get associate with a JavaBean in our Struts configuration
file. Java bean is nothing but a class having getter and setter methods that
can be used to communicate between the view and the controller layer.
These java beans are validated by invoking the validate() method on
the ActionForm by the help of the Struts system. The client sends the
request by the normal form submission by using Get or Post method, and
the Struts system updates that data in the Bean before calling the
controller components.

5. The view we use in the struts can be either Jsp page, Velocity templates,
XSLT pages etc. In struts there are set of JSP tags which has been
bundled with the struts distribution, but it is not mandatory to use only Jsp
tags, even plain HTML files can be used within our Struts application but
the disadvantage of using the html is that it can't take the full advantage
of all the dynamic features provided in the struts framework.
The framework includes a set of custom tag libraries that facilitate in
creating the user interfaces that can interact gracefully with ActionForm
beans. The struts Jsp taglibs has a number of generic and struts specific
tags tags which helps you to use dynamic data in your view. These tags
helps us to interact with your controller without writing much java code
inside your jsp. These tags are used create forms, internally forward to
other pages by interacting with the bean and helps us to invoke other
actions of the web application.
There are many tags provided to you in the struts frameworks which helps
you in sending error messages, internationalization etc.

Note: The points we have described above will be in effect if and only if when the
ActionServlet is handling the request. When the request is submitted to the
container which call the ActionServlet, make sure that the extension of the file
which we want to access should have the extension .do.

Struts working:
Process flow:

web.xml : Whenever the container gets start up the first work it does is to check
the web.xml file and determine what struts action Servlets exist. The container
is responsible for mapping all the file request to the correct action Servlet.

A Request : This is the second step performed by the container after checking
the web.xml file. In this the user submits a form within a browser and the request
is intercepted by the controller.

The Controller : This is the heart of the container. Most Struts application will
have only one controller that is ActionServlet which is responsible for directing
several Actions. The controller determines what action is required and sends the
information to be processed by an action Bean. The key advantage of having a
controller is its ability to control the flow of logic through the highly controlled,
centralized points.

struts.config.xml : Struts has a configuration file to store mappings of actions.


By using this file there is no need to hard code the module which will be called
within a component. The one more responsibility of the controller is to check the
struts.config.xml file to determine which module to be called upon an action
request. Struts only reads the struts.config.xml file upon start up.

Model : The model is basically a business logic part which takes the response
from the user and stores the result for the duration of the process. This is a great
place to perform the preprocessing of the data received from request. It is
possible to reuse the same model for many page requests. Struts provides the
ActionForm and the Action classes which can be extended to create the model
objects.

View : The view in struts framework is mainly a jsp page which is responsible for
producing the output to the user.

Struts tag libraries : These are struts components helps us to integrate the
struts framework within the project's logic. These struts tag libraries are used
within the JSP page. This means that the controller and the model part can't
make use of the tag library but instead use the struts class library for strut
process control.

Property file : It is used to store the messages that an object or page can use.
Properties files can be used to store the titles and other string data. We can
create many property files to handle different languages.

Business objects : It is the place where the rules of the actual project exists.
These are the modules which just regulate the day- to- day site activities.

The Response : This is the output of the View JSP object.

Components of Struts
1. Model Components:

- Many application’s focus is on the view. The processing required for each
submitted form / request by keeping the model’s perspective in view.

- In general the focus for handling the model components is done by the
creation of java beans that support the functionality requirements. The scope
concept is related to the beans is used first.

- The concept of extending ActionForm class is assumed by the Struts


framework for each input form.

- ActionForm is a bean that are declared in ActionMapping configurationfile.


- The struts controller servlet automatically performs the services required,
before invoking the appropriate Action method.

2. View Components:

- Struts supports the interacting input forms and used for building
internationalized applications.

- Some files are uploaded by using HTML forms. Most of the browsers support
the uploading of files through a input tag like <input type=”file”>. This
generates a file browse button. Struts handles these kind of forms in a way
that is identical to building normal forms.

3. Controller Components:

- The primary function of mapping request URI to an Action class that is


implemented by the servlet. This operation also included in Struts
framework. So, the Controller responsibilities include:

i. Write an Action class for every request that may be received.


ii. Configuring an ActionMapping, that is in the form of XML file, for every
logical requests that implements. The name of the file is struts-config.xml.
iii. Updating the deployment descriptor file for the application to include
the necessary components.
iv. Adding the struts components to the application.

Forms with Struts


Struts framework makes working with form easier than classic JSP/Servlet, by using a mapping
between form’s fields and JavaBean properties. In this tutorial, we are going to reveal how to handle
form in Struts way, by implementing a typical function of every web application - the login function.
To understand the way Struts handles form data, let’s look at the following picture:

As we can see, there are three components that involve in handling form in Struts application: Struts
form, JavaBean and Action class. The relationship between these components is clearly described in
the above picture: Fields in the form are mapped to properties of a JavaBean which is an attribute of
the action class that handles the form submission. In Struts, we don’t have to read values of the
form’s fields through a HTTP request object like in traditional JSP/Servlet. Instead, Struts will
automatically fetch values of form’s fields into the mapped JavaBean object. Then in the action
class, we can access the form’s fields just like accessing JavaBean properties. Thus this approach
simplifies form handling.

Now let’s walk through each in details.


1. Understand Form Handling in Struts
Struts provides its own form tags to render the HTML form. These tags are almost equivalent to
HTML ones, but provide mapping and relationship with the action class and JavaBean class. To use
Struts tag, it requires putting a taglib directive at the top of the JSP page like this:

<%@ taglib prefix="s" uri="/struts-tags" %>


The <s:form> tag

This tag will create a HTML-equivalent <form> tag. Typically we would use this tag as follows:

<s:form action="relative URL of action" method="post">


For example:

<s:form action="login" method="post">


The field tags

Inside the <s:form> tag we put tags to create HTML form fields in the following form:

<s:tagName name="beanName.propertyName" label="Field label" />


In the above syntax, beanName must be name of a member variable declared in the action class
(with appropriate getter and setter methods); tagName is one of the following form tags provided by
Struts: textfield, checkbox, radio, password, textarea, combobox… (See full list of Struts
form tags here). For example:

<s:textfield name="userBean.email" label="E-mail" />


<s:password name="userBean.password" label="Password" />
The <s:submit> tag

The <s:submit> tag simply create a submit button. For example:


o Default submit button: <s:submit />
o Submit button with custom label: <s:submit label="Login" />
And we have complete code of the form page (LoginForm.jsp) as follows:
1 <%@ page language="java" contentType="text/html; charset=UTF-8"

2 pageEncoding="UTF-8"%>

<%@ taglib prefix="s" uri="/struts-tags" %>


3
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
4
"http://www.w3.org/TR/html4/loose.dtd">
5
<html>
6
<head>
7
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8
9
<title>Login</title>
10
</head>
11
<body>
12 <div align="center">

13 <h2>Please login</h2>

14 <s:form action="login" method="post">

15 <s:textfield name="userBean.email" label="E-mail" />

16 <s:password name="userBean.password" label="Password" />

<s:submit value="Login" />


17
</s:form>
18
</div>
19
</body>
20
</html>
21

2. Code the JavaBean class


After the form, we need to create a JavaBean class which simply models the form with properties
mapped to the form’s fields. For the login form above, we should create the following JavaBean
class (User.java):

1 package net.codejava.struts;

3 public class User {

private String email;


4
private String password;
5

6
public String getEmail() {
7
return email;
8
}
9

10

11 public void setEmail(String email) {

this.email = email;
12
}
13

14
public String getPassword() {
15
return password;
16
}
17

18
public void setPassword(String password) {
19
this.password = password;
20 }

21 }

22

The properties email and password must match the properties defined in the login
form: userBean.email and userBean.password, respectively.

When the form is submitted, Struts will create an instance of this JavaBean class using the default,
no-arguments constructor. So make sure there’s always a no-arguments constructor in the class:


o If there’s no explicit constructor, then the compiler will generate a default, no-
argument constructor. In this case, we don’t have to do anything.
o If we declare a constructor has an argument like this:
1 public User(String email) {

2 this.email = email;

3 }

Then we have to write a non-argument constructor explicitly like this:


1 public User() {

2 }

Otherwise a NullpointerException will be thrown when the form is submitted.


3. Code the Struts Action class
Create the action class (LoginAction.java) with the following code:

1 package net.codejava.struts;

3 import com.opensymphony.xwork2.ActionSupport;

4
public class LoginAction extends ActionSupport {
5

6
private User userBean;
7

8
public String execute() {
9
System.out.println("email: " + userBean.getEmail());
10
System.out.println("pass: " + userBean.getPassword());
11

12
// add your login procedure here...
13

14
return SUCCESS;
15 }
16

17 public User getUserBean() {

18 return userBean;

19 }

20

21 public void setUserBean(User userBean) {

this.userBean = userBean;
22
}
23

24 }

25

Here we have to declare a member variable of type User called userBean to match with
the userBean name defined in the login form, with appropriate getter and setter methods.

Then in the action method execute(), we can access the email and password of the login form just
like reading properties of the userBean. Because before executing the action method, Struts
creates an instance of the User class and passes values of form’s fields into the appropriate setter
methods.

Inside the execute() method, we simply print out the email and password to the server’s console.
In reality, you may validate the email and password against a database, depending on how the login
function would be implemented.

Finally the action method returns SUCCESS view as usual.

4. Code the success page


Create a login-success.html file under WEB-INF\content directory of the application, with the
following content:

1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2
"http://www.w3.org/TR/html4/loose.dtd">
3 <html>
4 <head>

5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

6 <title>Login Success</title>

7 </head>

<body>
8
<h2 align="center">Welcome, you have logged in successfully!</h2>
9
</body>
10
</html>
11
This is a simple HTML page that displays a welcome message to the user. By convention, the
framework will show up this page when the action class returns SUCCESS view.

5. Configure Struts in web.xml


To enable Struts processing requests, configure it in the web.xml file as follows:
1 <?xml version="1.0" encoding="UTF-8"?>

2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee"
3
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
4
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
5
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
6
id="WebApp_ID" version="3.0">
7

8
<display-name>Struts2FormHandling</display-name>
9

10 <filter>
11 <filter-name>struts2</filter-name>

12 <filter-class>

13 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

14 </filter-class>

</filter>
15

16
<filter-mapping>
17
<filter-name>struts2</filter-name>
18
<url-pattern>/*</url-pattern>
19
</filter-mapping>
20
</web-app>
21
22

ATTENTION: We don’t use struts.xml

We don’t use the struts.xml file in this application. Instead, we use the default naming convention
implied by Struts. The following table shows how the framework will interpret the action URL and
view file:

Action class URL mapping Success view


LoginAction.java /login WEB-INF/content/login-success.html

Thanks to the Convention Plugin to make this possible. Remember to put the convention plugin’s jar
file into the classpath, e.g. struts2-convention-plugin-VERSION.jar.

For more information about this naming convention, see the tutorial: Struts beginner tutorial with
Convention Plugin.

If you build this application in Eclipse IDE, the project would have the following structure:
6. Testing the Struts From Handling application
Let’s deploy the application on Tomcat server with the context path /Struts2FormHandling. Type the
following URL into browser to show the login page:

http://localhost:8080/Struts2FormHandling/LoginForm.jsp
The login form appears:
Enter e-mail and password then hit Login button, the welcome page appears:

Look at the server’s console, we’ll see the entered e-mail and password are printed out.

Spring: Framework
Spring framework is an open source Java platform that provides comprehensive
infrastructure support for developing robust Java applications very easily and very
rapidly. Spring framework was initially written by Rod Johnson and was first released
under the Apache 2.0 license in June 2003. This tutorial has been written based on
Spring Framework version 4.1.6 released in Mar 2015.

Why to Learn Spring?


Spring is the most popular application development framework for enterprise Java.
Millions of developers around the world use Spring Framework to create high
performing, easily testable, and reusable code.
Spring framework is an open source Java platform. It was initially written by Rod
Johnson and was first released under the Apache 2.0 license in June 2003.
Spring is lightweight when it comes to size and transparency. The basic version of
Spring framework is around 2MB.
The core features of the Spring Framework can be used in developing any Java
application, but there are extensions for building web applications on top of the Java
EE platform. Spring framework targets to make J2EE development easier to use and
promotes good programming practices by enabling a POJO-based programming
model.

Applications of Spring
Following is the list of few of the great benefits of using Spring Framework −
 POJO Based - Spring enables developers to develop enterprise-class applications using
POJOs. The benefit of using only POJOs is that you do not need an EJB container product
such as an application server but you have the option of using only a robust servlet
container such as Tomcat or some commercial product.
 Modular - Spring is organized in a modular fashion. Even though the number of packages
and classes are substantial, you have to worry only about the ones you need and ignore the
rest.
 Integration with existing frameworks - Spring does not reinvent the wheel, instead it truly
makes use of some of the existing technologies like several ORM frameworks, logging
frameworks, JEE, Quartz and JDK timers, and other view technologies.
 Testablity - Testing an application written with Spring is simple because environment-
dependent code is moved into this framework. Furthermore, by using JavaBeanstyle
POJOs, it becomes easier to use dependency injection for injecting test data.
 Web MVC - Spring's web framework is a well-designed web MVC framework, which
provides a great alternative to web frameworks such as Struts or other over-engineered or
less popular web frameworks.
 Central Exception Handling - Spring provides a convenient API to translate technology-
specific exceptions (thrown by JDBC, Hibernate, or JDO, for example) into consistent,
unchecked exceptions.
 Lightweight - Lightweight IoC containers tend to be lightweight, especially when compared
to EJB containers, for example. This is beneficial for developing and deploying applications
on computers with limited memory and CPU resources.
 Transaction management - Spring provides a consistent transaction management
interface that can scale down to a local transaction (using a single database, for example)
and scale up to global transactions (using JTA, for example).

1.Spring - JDBC Framework Overview


While working with the database using plain old JDBC, it becomes cumbersome to
write unnecessary code to handle exceptions, opening and closing database
connections, etc. However, Spring JDBC Framework takes care of all the low-level
details starting from opening the connection, prepare and execute the SQL statement,
process exceptions, handle transactions and finally close the connection.
So what you have to do is just define the connection parameters and specify the SQL
statement to be executed and do the required work for each iteration while fetching
data from the database.
Spring JDBC provides several approaches and correspondingly different classes to
interface with the database. I'm going to take classic and the most popular approach
which makes use of JdbcTemplate class of the framework. This is the central
framework class that manages all the database communication and exception
handling.

JdbcTemplate Class
The JDBC Template class executes SQL queries, updates statements, stores
procedure calls, performs iteration over ResultSets, and extracts returned parameter
values. It also catches JDBC exceptions and translates them to the generic, more
informative, exception hierarchy defined in the org.springframework.dao package.
Instances of the JdbcTemplate class are threadsafe once configured. So you can
configure a single instance of a JdbcTemplate and then safely inject this shared
reference into multiple DAOs.
A common practice when using the JDBC Template class is to configure
a DataSource in your Spring configuration file, and then dependency-inject that shared
DataSource bean into your DAO classes, and the JdbcTemplate is created in the setter
for the DataSource.

Configuring Data Source


Let us create a database table Student in our database TEST. We assume you are
working with MySQL database, if you work with any other database then you can
change your DDL and SQL queries accordingly.
CREATE TABLE Student(
ID INT NOT NULL AUTO_INCREMENT,
NAME VARCHAR(20) NOT NULL,
AGE INT NOT NULL,
PRIMARY KEY (ID)
);

Now we need to supply a DataSource to the JDBC Template so it can configure itself to
get database access. You can configure the DataSource in the XML file with a piece of
code as shown in the following code snippet −
<bean id = "dataSource"
class =
"org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name = "driverClassName" value =
"com.mysql.jdbc.Driver"/>
<property name = "url" value =
"jdbc:mysql://localhost:3306/TEST"/>
<property name = "username" value = "root"/>
<property name = "password" value = "password"/>
</bean>

Data Access Object (DAO)


DAO stands for Data Access Object, which is commonly used for database interaction.
DAOs exist to provide a means to read and write data to the database and they should
expose this functionality through an interface by which the rest of the application will
access them.
The DAO support in Spring makes it easy to work with data access technologies like
JDBC, Hibernate, JPA, or JDO in a consistent way.

Executing SQL statements


Let us see how we can perform CRUD (Create, Read, Update and Delete) operation
on database tables using SQL and JDBC Template object.
Querying for an integer
String SQL = "select count(*) from Student";
int rowCount = jdbcTemplateObject.queryForInt( SQL );

Querying for a long


String SQL = "select count(*) from Student";
long rowCount = jdbcTemplateObject.queryForLong( SQL );

A simple query using a bind variable


String SQL = "select age from Student where id = ?";
int age = jdbcTemplateObject.queryForInt(SQL, new Object[]{10});

Querying for a String


String SQL = "select name from Student where id = ?";
String name = jdbcTemplateObject.queryForObject(SQL, new Object[]
{10}, String.class);

Querying and returning an object


String SQL = "select * from Student where id = ?";
Student student = jdbcTemplateObject.queryForObject(
SQL, new Object[]{10}, new StudentMapper());

public class StudentMapper implements RowMapper<Student> {


public Student mapRow(ResultSet rs, int rowNum) throws
SQLException {
Student student = new Student();
student.setID(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));

return student;
}
}

Querying and returning multiple objects


String SQL = "select * from Student";
List<Student> students = jdbcTemplateObject.query(
SQL, new StudentMapper());

public class StudentMapper implements RowMapper<Student> {


public Student mapRow(ResultSet rs, int rowNum) throws
SQLException {
Student student = new Student();
student.setID(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));

return student;
}
}

Inserting a row into the table


String SQL = "insert into Student (name, age) values (?, ?)";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 11} );

Updating a row into the table


String SQL = "update Student set name = ? where id = ?";
jdbcTemplateObject.update( SQL, new Object[]{"Zara", 10} );

Deleting a row from the table


String SQL = "delete Student where id = ?";
jdbcTemplateObject.update( SQL, new Object[]{20} );

Executing DDL Statements


You can use the execute(..) method from jdbcTemplate to execute any SQL
statements or DDL statements. Following is an example to use CREATE statement to
create a table −
String SQL = "CREATE TABLE Student( " +
"ID INT NOT NULL AUTO_INCREMENT, " +
"NAME VARCHAR(20) NOT NULL, " +
"AGE INT NOT NULL, " +
"PRIMARY KEY (ID));"

jdbcTemplateObject.execute( SQL );

Spring JDBC Framework Examples


Based on the above concepts, let us check few important examples which will help you in
understanding usage of JDBC framework in Spring −

Sr.No. Example & Description

1 Spring JDBC Example

This example will explain how to write a simple JDBC-based Spring application.

2 SQL Stored Procedure in Spring

Learn how to call SQL stored procedure while using JDBC in Spring.

2.Spring - MVC Framework


The Spring Web MVC framework provides Model-View-Controller (MVC) architecture
and ready components that can be used to develop flexible and loosely coupled web
applications. The MVC pattern results in separating the different aspects of the
application (input logic, business logic, and UI logic), while providing a loose coupling
between these elements.
 The Model encapsulates the application data and in general they will consist of POJO.
 The View is responsible for rendering the model data and in general it generates HTML
output that the client's browser can interpret.
 The Controller is responsible for processing user requests and building an appropriate
model and passes it to the view for rendering.

The DispatcherServlet
The Spring Web model-view-controller (MVC) framework is designed around
a DispatcherServlet that handles all the HTTP requests and responses. The request
processing workflow of the Spring Web MVC DispatcherServlet is illustrated in the
following diagram −
Following is the sequence of events corresponding to an incoming HTTP request
to DispatcherServlet −
 After receiving an HTTP request, DispatcherServlet consults the HandlerMapping to call the
appropriate Controller.
 The Controller takes the request and calls the appropriate service methods based on used
GET or POST method. The service method will set model data based on defined business
logic and returns view name to the DispatcherServlet.
 The DispatcherServlet will take help from ViewResolver to pickup the defined view for the
request.
 Once view is finalized, The DispatcherServlet passes the model data to the view which is
finally rendered on the browser.
All the above-mentioned components, i.e. HandlerMapping, Controller, and
ViewResolver are parts of WebApplicationContext w which is an extension of the
plainApplicationContext with some extra features necessary for web applications.

Required Configuration
You need to map requests that you want the DispatcherServlet to handle, by using a
URL mapping in the web.xml file. The following is an example to show declaration and
mapping for HelloWeb DispatcherServlet example −
<web-app id = "WebApp_ID" version = "2.4"
xmlns = "http://java.sun.com/xml/ns/j2ee"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring MVC Application</display-name>

<servlet>
<servlet-name>HelloWeb</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>HelloWeb</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>

</web-app>

The web.xml file will be kept in the WebContent/WEB-INF directory of your web
application. Upon initialization of HelloWeb DispatcherServlet, the framework will try to
load the application context from a file named [servlet-name]-servlet.xml located in
the application's WebContent/WEB-INFdirectory. In this case, our file will
be HelloWebservlet.xml.
Next, <servlet-mapping> tag indicates what URLs will be handled by which
DispatcherServlet. Here all the HTTP requests ending with .jsp will be handled by
the HelloWeb DispatcherServlet.
If you do not want to go with default filename as [servlet-name]-servlet.xml and default
location as WebContent/WEB-INF, you can customize this file name and location by
adding the servlet listener ContextLoaderListener in your web.xml file as follows −
<web-app...>

<!-------- DispatcherServlet definition goes here----->


....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/HelloWeb-servlet.xml</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

</web-app>

Now, let us check the required configuration for HelloWeb-servlet.xml file, placed in
your web application's WebContent/WEB-INF directory −
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:context = "http://www.springframework.org/schema/context"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation =
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-
3.0.xsd">

<context:component-scan base-package = "com.tutorialspoint" />

<bean class =
"org.springframework.web.servlet.view.InternalResourceViewResolver"
>
<property name = "prefix" value = "/WEB-INF/jsp/" />
<property name = "suffix" value = ".jsp" />
</bean>

</beans>

Following are the important points about HelloWeb-servlet.xml file −


 The [servlet-name]-servlet.xml file will be used to create the beans defined, overriding the
definitions of any beans defined with the same name in the global scope.
 The <context:component-scan...> tag will be use to activate Spring MVC annotation
scanning capability which allows to make use of annotations like @Controller and
@RequestMapping etc.
 The InternalResourceViewResolver will have rules defined to resolve the view names. As
per the above defined rule, a logical view named hello is delegated to a view
implementation located at /WEB-INF/jsp/hello.jsp .
The following section will show you how to create your actual components, i.e.,
Controller, Model, and View.

Defining a Controller
The DispatcherServlet delegates the request to the controllers to execute the
functionality specific to it. The @Controllerannotation indicates that a particular class
serves the role of a controller. The @RequestMapping annotation is used to map a
URL to either an entire class or a particular handler method.
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}

The @Controller annotation defines the class as a Spring MVC controller. Here, the
first usage of @RequestMapping indicates that all handling methods on this controller
are relative to the /hello path. Next annotation@RequestMapping(method =
RequestMethod.GET) is used to declare theprintHello() method as the controller's
default service method to handle HTTP GET request. You can define another method
to handle any POST request at the same URL.
You can write the above controller in another form where you can add additional
attributes in @RequestMapping as follows −
@Controller
public class HelloController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}

The value attribute indicates the URL to which the handler method is mapped and
the method attribute defines the service method to handle HTTP GET request. The
following important points are to be noted about the controller defined above −
 You will define required business logic inside a service method. You can call another method
inside this method as per requirement.
 Based on the business logic defined, you will create a model within this method. You can
use setter different model attributes and these attributes will be accessed by the view to
present the final result. This example creates a model with its attribute "message".
 A defined service method can return a String, which contains the name of the view to be
used to render the model. This example returns "hello" as logical view name.

Creating JSP Views


Spring MVC supports many types of views for different presentation technologies.
These include - JSPs, HTML, PDF, Excel worksheets, XML, Velocity templates, XSLT,
JSON, Atom and RSS feeds, JasperReports, etc. But most commonly we use JSP
templates written with JSTL.
Let us write a simple hello view in /WEB-INF/hello/hello.jsp −
<html>
<head>
<title>Hello Spring MVC</title>
</head>

<body>
<h2>${message}</h2>
</body>
</html>

Here ${message} is the attribute which we have set up inside the Controller. You can
have multiple attributes to be displayed inside your view.

Hibernate
Hibernate - Configuration Settings
Hibernate requires to know in advance — where to find the mapping information that
defines how your Java classes relate to the database tables. Hibernate also requires a
set of configuration settings related to database and other related parameters. All such
information is usually supplied as a standard Java properties file
called hibernate.properties, or as an XML file named hibernate.cfg.xml.
I will consider XML formatted file hibernate.cfg.xml to specify required Hibernate
properties in my examples. Most of the properties take their default values and it is not
required to specify them in the property file unless it is really required. This file is kept
in the root directory of your application's classpath.

Hibernate Properties
Following is the list of important properties, you will be required to configure for a databases in
a standalone situation −

Sr.No. Properties & Description

1
hibernate.dialect
This property makes Hibernate generate the appropriate SQL for the chosen database.

2
hibernate.connection.driver_class
The JDBC driver class.

3
hibernate.connection.url
The JDBC URL to the database instance.

4
hibernate.connection.username
The database username.

5
hibernate.connection.password
The database password.

6
hibernate.connection.pool_size
Limits the number of connections waiting in the Hibernate database connection pool.

7
hibernate.connection.autocommit
Allows autocommit mode to be used for the JDBC connection.

If you are using a database along with an application server and JNDI, then you would
have to configure the following properties −

Sr.No. Properties & Description

1
hibernate.connection.datasource
The JNDI name defined in the application server context, which you are using for the application.

2
hibernate.jndi.class
The InitialContext class for JNDI.

3
hibernate.jndi.<JNDIpropertyname>
Passes any JNDI property you like to the JNDI InitialContext.

4
hibernate.jndi.url
Provides the URL for JNDI.

5
hibernate.connection.username
The database username.

6
hibernate.connection.password
The database password.
Hibernate with MySQL Database
MySQL is one of the most popular open-source database systems available today. Let
us create hibernate.cfg.xml configuration file and place it in the root of your
application's classpath. You will have to make sure that you have testdb database
available in your MySQL database and you have a user test available to access the
database.
The XML configuration file must conform to the Hibernate 3 Configuration DTD, which
is available at http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd.
<?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.MySQLDialect
</property>

<property name = "hibernate.connection.driver_class">


com.mysql.jdbc.Driver
</property>

<!-- Assume test is the database name -->

<property name = "hibernate.connection.url">


jdbc:mysql://localhost/test
</property>

<property name = "hibernate.connection.username">


root
</property>

<property name = "hibernate.connection.password">


root123
</property>

<!-- List of XML mapping files -->


<mapping resource = "Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>

The above configuration file includes <mapping> tags, which are related to
hibernatemapping file and we will see in next chapter what exactly a hibernate
mapping file is and how and why do we use it?
Following is the list of various important databases dialect property type −
Sr.No. Database & Dialect Property

1
DB2
org.hibernate.dialect.DB2Dialect

2
HSQLDB
org.hibernate.dialect.HSQLDialect

3
HypersonicSQL
org.hibernate.dialect.HSQLDialect

4
Informix
org.hibernate.dialect.InformixDialect

5
Ingres
org.hibernate.dialect.IngresDialect

6
Interbase
org.hibernate.dialect.InterbaseDialect

7
Microsoft SQL Server 2000
org.hibernate.dialect.SQLServerDialect

8
Microsoft SQL Server 2005
org.hibernate.dialect.SQLServer2005Dialect

9
Microsoft SQL Server 2008
org.hibernate.dialect.SQLServer2008Dialect

10
MySQL
org.hibernate.dialect.MySQLDialect

11
Oracle (any version)
org.hibernate.dialect.OracleDialect

12
Oracle 11g
org.hibernate.dialect.Oracle10gDialect

13
Oracle 10g
org.hibernate.dialect.Oracle10gDialect

14
Oracle 9i
org.hibernate.dialect.Oracle9iDialect

15
PostgreSQL
org.hibernate.dialect.PostgreSQLDialect

16
Progress
org.hibernate.dialect.ProgressDialect

17
SAP DB
org.hibernate.dialect.SAPDBDialect

18
Sybase
org.hibernate.dialect.SybaseDialect

19
Sybase Anywhere
org.hibernate.dialect.SybaseAnywhereDialect

Mapping persistent classes (Hibernate)


The entire concept of Hibernate is to take the values from Java class attributes and
persist them to a database table. A mapping document helps Hibernate in determining
how to pull the values from the classes and map them with table and associated fields.
Java classes whose objects or instances will be stored in database tables are called
persistent classes in Hibernate. Hibernate works best if these classes follow some
simple rules, also known as the Plain Old Java Object (POJO) programming model.
There are following main rules of persistent classes, however, none of these rules are
hard requirements −
 All Java classes that will be persisted need a default constructor.
 All classes should contain an ID in order to allow easy identification of your objects within
Hibernate and the database. This property maps to the primary key column of a database
table.
 All attributes that will be persisted should be declared private and
have getXXX and setXXX methods defined in the JavaBean style.
 A central feature of Hibernate, proxies, depends upon the persistent class being either non-
final, or the implementation of an interface that declares all public methods.
 All classes that do not extend or implement some specialized classes and interfaces
required by the EJB framework.
The POJO name is used to emphasize that a given object is an ordinary Java Object,
not a special object, and in particular not an Enterprise JavaBean.

Simple POJO Example


Based on the few rules mentioned above, we can define a POJO class as follows −
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;

public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}

public int getId() {


return id;
}

public void setId( int id ) {


this.id = id;
}

public String getFirstName() {


return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}

public String getLastName() {


return lastName;
}

public void setLastName( String last_name ) {


this.lastName = last_name;
}

public int getSalary() {


return salary;
}

public void setSalary( int salary ) {


this.salary = salary;
}
}

Working with persistent objects


The persistence lifecycle
Because Hibernate is a transparent persistence mechanism—classes are unaware of
their own persistence capability—it’s possible to write application logic that is unaware
whether the objects it operates on represent persistent state or temporary state that
exists only in memory. The application shouldn’t necessarily need to care that an object
is persistent when invoking its methods. You can, for example, invoke the
calculateTotalPrice() business method on an instance of the Item class without having to
consider persistence at all; e.g., in a unit test.

Any application with persistent state must interact with the persistence service
whenever it needs to propagate state held in memory to the database (or vice versa). In
other words, you have to call Hibernate (or the Java Persistence) interfaces to store and
load objects.

When interacting with the persistence mechanism in that way, it’s necessary for the
application to concern itself with the state and lifecycle of an object with respect to
persistence. We refer to this as the persistence lifecycle: the states an object goes
through during its life. We also use the term unit of work: a set of operations you
consider one (usually atomic) group. Another piece of the puzzle is the persistence
context provided by the persistence service. Think of the persistence context as a cache
that remembers all the modifications and state changes you made to objects in a
particular unit of work (this is somewhat simplified, but it’s a good starting point).
We now dissect all these terms: object and entity states, persistence contexts, and
managed scope. You’re probably more accustomed to thinking about what statements
you have to manage to get stuff in and out of the database (via JDBC and SQL).
However, one of the key factors of your success with Hibernate (and Java Persistence)
is your understanding of state management, so stick with us through this section.

Object states
Different ORM solutions use different terminology and define different states and
state transitions for the persistence lifecycle. Moreover, the object states used internally
may be different from those exposed to the client application. Hibernate defines only
four states, hiding the complexity of its internal implementation from the client code.
The object states defined by Hibernate and their transitions in a state chart are shown in
figure 9.1. You can also see the method calls to the persistence manager API that
trigger transitions. This API in Hibernate is the Session. We discuss this chart in this
topic; refer to it whenever you need an overview.

We’ve also included the states ofJava Persistence entity instances in figure 9.1. As you
can see, they’re almost equivalent to Hibernate’s, and most methods of the Session
have a counterpart on the EntityManager API (shown in italics). We say that Hibernate
is a superset of the functionality provided by the subset standardized in Java
Persistence.

Some methods are available on both APIs; for example, the Session has a per-sist()
operation with the same semantics as the EntityManager’s counterpart. Others, like
load() and getReference(), also share semantics, with a different method name.

During its life, an object can transition from a transient object to a persistent object to a
detached object. Let’s explore the states and transitions in more detail.
Figure 9.1 Object states and their transitions as triggered by persistence manager
operations

Transient objects
Objects instantiated using the new operator aren’t immediately persistent. Their state is
transient, which means they aren’t associated with any database table row and so their
state is lost as soon as they’re no longer referenced by any other object. These objects
have a lifespan that effectively ends at that time, and they become inaccessible and
available for garbage collection. Java Persistence doesn’t include a term for this state;
entity objects you just instantiated are new. We’ll continue to refer to them as transient
to emphasize the potential for these instances to become managed by a persistence
service.

Hibernate and Java Persistence consider all transient instances to be nontransactional;


any modification of a transient instance isn’t known to a persistence context. This
means that Hibernate doesn’t provide any roll-back functionality for transient objects.

Objects that are referenced only by other transient instances are, by default, also
transient. For an instance to transition from transient to persistent state, to become
managed, requires either a call to the persistence manager or the creation of a
reference from an already persistent instance.
Persistent objects
A persistent instance is an entity instance with a database identity, as defined.
“Mapping entities with identity.” That means a persistent and managed instance has a
primary key value set as its database identifier. (There are some variations to when this
identifier is assigned to a persistent instance.)
Persistent instances may be objects instantiated by the application and then made
persistent by calling one of the methods on the persistence manager. They may even
be objects that became persistent when a reference was created from another
persistent object that is already managed. Alternatively, a persistent instance may be an
instance retrieved from the database by execution of a query, by an identifier lookup, or
by navigating the object graph starting from another persistent instance.
Persistent instances are always associated with a persistence context. Hibernate
caches them and can detect whether they have been modified by the application.
There is much more to be said about this state and how an instance is managed in a
persistence context. We’ll get back to this later in this topic.

Removed objects
You can delete an entity instance in several ways: For example, you can remove it with
an explicit operation of the persistence manager. It may also become available for
deletion if you remove all references to it, a feature available only in Hibernate or in
Java Persistence with a Hibernate extension setting (orphan deletion for entities).

An object is in the removed state if it has been scheduled for deletion at the end of a
unit of work, but it’s still managed by the persistence context until the unit of work
completes. In other words, a removed object shouldn’t be reused because it will be
deleted from the database as soon as the unit of work completes. You should also
discard any references you may hold to it in the application (of course, after you finish
working with it—for example, after you’ve rendered the removal-confirmation screen
your users see).

Detached objects
To understand detached objects, you need to consider a typical transition of an
instance: First it’s transient, because it just has been created in the application. Now
you make it persistent by calling an operation on the persistence manager. All of this
happens in a single unit of work, and the persistence context for this unit of work is
synchronized with the database at some point (when an SQL INSERT occurs).
The unit of work is now completed, and the persistence context is closed. But the
application still has a handle: a reference to the instance that was saved. As long as the
persistence context is active, the state of this instance is persistent. At the end of a unit
of work, the persistence context closes. What is the state of the object you’re holding a
reference to now, and what can you do with it?
We refer to these objects as detached, indicating that their state is no longer
guaranteed to be synchronized with database state; they’re no longer attached to a
persistence context. They still contain persistent data (which may soon be stale). You
can continue working with a detached object and modify it. However, at some point you
probably want to make those changes persistent—in other words, bring the detached
instance back into persistent state.
Hibernate offers two operations, reattachment and merging, to deal with this
situation. Java Persistence only standardizes merging. These features have a deep
impact on how multitiered applications may be designed. The ability to return objects
from one persistence context to the presentation layer and later reuse them in a new
persistence context is a main selling point of Hibernate and Java Persistence. It enables
you to create long units of work that span user think-time. We call this kind of long-
running unit of work a conversation. We’ll get back to detached objects and
conversations soon.
You should now have a basic understanding of object states and how transitions occur.
Our next topic is the persistence context and the management of objects it provides.

The persistence context


You may consider the persistence context to be a cache of managed entity instances.
The persistence context isn’t something you see in your application; it isn’t an API you
can call. In a Hibernate application, we say that one Session has one internal
persistence context. In a Java Persistence application, an EntityManager has a
persistence context. All entities in persistent state and managed in a unit of work are
cached in this context. We walk through the Session and EntityManager APIs later in
this topic. Now you need to know what this (internal) persistence context is buying you.

The persistence context is useful for several reasons:


■ Hibernate can do automatic dirty checking and transactional write-behind.

■ Hibernate can use the persistence context as a first-level cache.

■ Hibernate can guarantee a scope of Java object identity.

■ Hibernate can extend the persistence context to span a whole conversation.

All these points are also valid for Java Persistence providers. Let’s look at each feature.

Automatic dirty checking


Persistent instances are managed in a persistence context—their state is
synchronized with the database at the end of the unit of work. When a unit of work
completes, state held in memory is propagated to the database by the execution of SQL
INSERT, UPDATE, and DELETE statements (DML). This procedure may also occur at
other times. For example, Hibernate may synchronize with the database before
execution of a query. This ensures that queries are aware of changes made earlier
during the unit of work.
Hibernate doesn’t update the database row of every single persistent object in
memory at the end of the unit of work. ORM software must have a strategy for detecting
which persistent objects have been modified by the application. We call this automatic
dirty checking. An object with modifications that have not yet been propagated to the
database is considered dirty. Again, this state isn’t visible to the application. With
transparent transaction-level write-behind, Hibernate propagates state changes to the
database as late as possible but hides this detail from the application. By executing
DML as late as possible (toward the end of the database transaction), Hibernate tries to
keep lock-times in the database as short as possible. (DML usually creates locks in the
database that are held until the transaction completes.)
Hibernate is able to detect exactly which properties have been modified so that it’s
possible to include only the columns that need updating in the SQL UPDATE statement.
This may bring some performance gains. However, it’s usually not a significant
difference and, in theory, could harm performance in some environments. By default,
Hibernate includes all columns of a mapped table in the SQL UPDATE statement
(hence, Hibernate can generate this basic SQL at startup, not at runtime). If you want to
update only modified columns, you can enable dynamic SQL generation by setting
dynamic-update=”true” in a class mapping. The same mechanism is implemented for
insertion of new records, and you can enable runtime generation of INSERT statements
with dynamic-insert=”true”. We recommend you consider this setting when you have an
extraordinarily large number of columns in a table (say, more than 50); at some point,
the overhead network traffic for unchanged fields will be noticeable.
In rare cases, you may also want to supply your own dirty checking algorithm to
Hibernate. By default, Hibernate compares an old snapshot of an object with the
snapshot at synchronization time, and it detects any modifications that require an
update of the database state. You can implement your own routine by supplying a
custom findDirty() method with an org.hibernate.Interceptor for a Session. We’ll show
you an implementation of an interceptor later in the topic.
We’ll also get back to the synchronization process (known as flushing) and when it
occurs later in this topic.

The persistence context cache


A persistence context is a cache of persistent entity instances. This means it
remembers all persistent entity instances you’ve handled in a particular unit of work.
Automatic dirty checking is one of the benefits of this caching. Another benefit is
repeatable read for entities and the performance advantage of a unit of work-scoped
cache.
For example, if Hibernate is told to load an object by primary key (a lookup by
identifier), it can first check the persistence context for the current unit of work. If the
entity is found there, no database hit occurs—this is a repeatable read for an
application. The same is true if a query is executed through one of the Hibernate (or
Java Persistence) interfaces. Hibernate reads the result set of the query and marshals
entity objects that are then returned to the application. During this process, Hibernate
interacts with the current persistence context. It tries to resolve every entity instance in
this cache (by identifier); only if the instance can’t be found in the current persistence
context does Hibernate read the rest of the data from the result set.
The persistence context cache offers significant performance benefits and improves the
isolation guarantees in a unit of work (you get repeatable read of entity instances for
free). Because this cache only has the scope of a unit of work, it has no real
disadvantages, such as lock management for concurrent access—a unit of work is
processed in a single thread at a time.

The persistence context cache sometimes helps avoid unnecessary


database traffic; but, more important, it ensures that:
■ The persistence layer isn’t vulnerable to stack overflows in the case of circular
references in a graph of objects.
■ There can never be conflicting representations of the same database row at the
end of a unit of work. In the persistence context, at most a single object represents any
database row. All changes made to that object may be safely written to the database.
■ Likewise, changes made in a particular persistence context are always immediately
visible to all other code executed inside that persistence context and its unit of work (the
repeatable read for entities guarantee).
You don’t have to do anything special to enable the persistence context cache. It’s
always on and, for the reasons shown, can’t be turned off.

Later in this topic, we’ll show you how objects are added to this cache (basically,
whenever they become persistent) and how you can manage this cache (by detaching
objects manually from the persistence context, or by clearing the persistence context).
The last two items on our list of benefits of a persistence context, the guaranteed scope
of identity and the possibility to extend the persistence context to span a conversation,
are closely related concepts. To understand them, you need to take a step back and
consider objects in detached state from a different perspective.

Object identity and equality


A basic Hibernate client/server application may be designed with server-side units of
work that span a single client request. When a request from the application user
requires data access, a new unit of work is started. The unit of work ends when
processing is complete and the response for the user is ready. This is also called the
session-per-request strategy (you can replace the word session with persistence
context whenever you read something like this, but it doesn’t roll off the tongue as well).
We already mentioned that Hibernate can support an implementation of a possibly long-
running unit of work, called a conversation. We introduce the concept of conversations
in the following sections as well as the fundamentals of object identity and when objects
are considered equal—which can impact how you think about and design
conversations.
Hibernate – Caching
Caching is a mechanism to enhance the performance of a system. It is a buffer
memorythat lies between the application and the database. Cache memory stores
recently used data items in order to reduce the number of database hits as much as
possible.
Caching is important to Hibernate as well. It utilizes a multilevel caching scheme as
explained below −

First-level Cache
The first-level cache is the Session cache and is a mandatory cache through which all
requests must pass. The Session object keeps an object under its own power before
committing it to the database.
If you issue multiple updates to an object, Hibernate tries to delay doing the update as
long as possible to reduce the number of update SQL statements issued. If you close
the session, all the objects being cached are lost and either persisted or updated in the
database.
Second-level Cache
Second level cache is an optional cache and first-level cache will always be consulted
before any attempt is made to locate an object in the second-level cache. The second
level cache can be configured on a per-class and per-collection basis and mainly
responsible for caching objects across sessions.
Any third-party cache can be used with Hibernate.
An org.hibernate.cache.CacheProvider interface is provided, which must be
implemented to provide Hibernate with a handle to the cache implementation.

Query-level Cache
Hibernate also implements a cache for query resultsets that integrates closely with the
second-level cache.
This is an optional feature and requires two additional physical cache regions that hold
the cached query results and the timestamps when a table was last updated. This is
only useful for queries that are run frequently with the same parameters.

The Second Level Cache


Hibernate uses first-level cache by default and you have nothing to do to use first-level
cache. Let's go straight to the optional second-level cache. Not all classes benefit from
caching, so it's important to be able to disable the second-level cache.
The Hibernate second-level cache is set up in two steps. First, you have to decide
which concurrency strategy to use. After that, you configure cache expiration and
physical cache attributes using the cache provider.

Concurrency Strategies
A concurrency strategy is a mediator, which is responsible for storing items of data in
the cache and retrieving them from the cache. If you are going to enable a second-
level cache, you will have to decide, for each persistent class and collection, which
cache concurrency strategy to use.
 Transactional − Use this strategy for read-mostly data where it is critical to prevent stale
data in concurrent transactions, in the rare case of an update.
 Read-write − Again use this strategy for read-mostly data where it is critical to prevent stale
data in concurrent transactions, in the rare case of an update.
 Nonstrict-read-write − This strategy makes no guarantee of consistency between the
cache and the database. Use this strategy if data hardly ever changes and a small
likelihood of stale data is not of critical concern.
 Read-only − A concurrency strategy suitable for data, which never changes. Use it for
reference data only.
If we are going to use second-level caching for our Employee class, let us add the
mapping element required to tell Hibernate to cache Employee instances using read-
write strategy.
<?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 = "Employee" table = "EMPLOYEE">

<meta attribute = "class-description">


This class contains the employee detail.
</meta>

<cache usage = "read-write"/>

<id name = "id" type = "int" column = "id">


<generator class="native"/>
</id>

<property name = "firstName" column = "first_name" type =


"string"/>
<property name = "lastName" column = "last_name" type =
"string"/>
<property name = "salary" column = "salary" type = "int"/>

</class>
</hibernate-mapping>

The usage="read-write" attribute tells Hibernate to use a read-write concurrency


strategy for the defined cache.

Cache Provider
Your next step after considering the concurrency strategies, you will use your cache candidate
classes to pick a cache provider. Hibernate forces you to choose a single cache provider for the
whole application.

Sr.No. Cache Name & Description

1
EHCache
It can cache in memory or on disk and clustered caching and it supports the optional Hibernate query
result cache.

2
OSCache
Supports caching to memory and disk in a single JVM with a rich set of expiration policies and query
cache support.

3
warmCache
A cluster cache based on JGroups. It uses clustered invalidation, but doesn't support the Hibernate
query cache.

4
JBoss Cache
A fully transactional replicated clustered cache also based on the JGroups multicast library. It supports
replication or invalidation, synchronous or asynchronous communication, and optimistic and pessimistic
locking. The Hibernate query cache is supported.

Every cache provider is not compatible with every concurrency strategy. The following
compatibility matrix will help you choose an appropriate combination.

Strategy/Provider Read-only Nonstrictread-write Read-write Transactional

EHCache X X X

OSCache X X X

SwarmCache X X

JBoss Cache X X

You will specify a cache provider in hibernate.cfg.xml configuration file. We choose


EHCache as our second-level cache provider −
<?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.MySQLDialect
</property>

<property name = "hibernate.connection.driver_class">


com.mysql.jdbc.Driver
</property>

<!-- Assume students is the database name -->

<property name = "hibernate.connection.url">


jdbc:mysql://localhost/test
</property>

<property name = "hibernate.connection.username">


root
</property>

<property name = "hibernate.connection.password">


root123
</property>

<property name = "hibernate.cache.provider_class">


org.hibernate.cache.EhCacheProvider
</property>

<!-- List of XML mapping files -->


<mapping resource = "Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>

Now, you need to specify the properties of the cache regions. EHCache has its own
configuration file, ehcache.xml, which should be in the CLASSPATH of the application.
A cache configuration in ehcache.xml for the Employee class may look like this −
<diskStore path="java.io.tmpdir"/>

<defaultCache
maxElementsInMemory = "1000"
eternal = "false"
timeToIdleSeconds = "120"
timeToLiveSeconds = "120"
overflowToDisk = "true"
/>

<cache name = "Employee"


maxElementsInMemory = "500"
eternal = "true"
timeToIdleSeconds = "0"
timeToLiveSeconds = "0"
overflowToDisk = "false"
/>

That's it, now we have second-level caching enabled for the Employee class and
Hibernate, now hits the second-level cache whenever you navigate to an Employee or
when you load an Employee by identifier.
You should analyze your all the classes and choose appropriate caching strategy for
each of the classes. Sometime, second-level caching may downgrade the performance
of the application. So, it is recommended to benchmark your application first, without
enabling caching and later on enable your well suited caching and check the
performance. If caching is not improving system performance, then there is no point in
enabling any type of caching.

The Query-level Cache


To use the query cache, you must first activate it using
the hibernate.cache.use_query_cache="true" property in the configuration file. By
setting this property to true, you make Hibernate create the necessary caches in
memory to hold the query and identifier sets.
Next, to use the query cache, you use the setCacheable(Boolean) method of the Query
class. For example −
Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

Hibernate also supports very fine-grained cache support through the concept of a
cache region. A cache region is part of the cache that's given a name.
Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

This code uses the method to tell Hibernate to store and look for the query in the
employee area of the cache.

Transactions and Concurrency in Hibernate


The most important point about Hibernate and concurrency control is that it is easy to
understand. Hibernate directly uses JDBC connections and JTA resources without adding any
additional locking behavior. It is recommended that you spend some time with the JDBC, ANSI,
and transaction isolation specification of your database management system.

Hibernate does not lock objects in memory. Your application can expect the behavior as defined
by the isolation level of your database transactions. Through Session, which is also a transaction-
scoped cache, Hibernate provides repeatable reads for lookup by identifier and entity queries and
not reporting queries that return scalar values.
In addition to versioning for automatic optimistic concurrency control, Hibernate also offers,
using the SELECT FOR UPDATE syntax, a (minor) API for pessimistic locking of rows.
Optimistic concurrency control and this API are discussed later in this chapter.

The discussion of concurrency control in Hibernate begins with the granularity


of Configuration, SessionFactory, and Session, as well as database transactions and long
conversations.

11.1. Session and transaction scopes

A SessionFactory is an expensive-to-create, threadsafe object, intended to be shared by all


application threads. It is created once, usually on application startup, from
a Configuration instance.

A Session is an inexpensive, non-threadsafe object that should be used once and then discarded
for: a single request, a conversation or a single unit of work. A Session will not obtain a
JDBC Connection, or a Datasource, unless it is needed. It will not consume any resources until
used.

In order to reduce lock contention in the database, a database transaction has to be as short as
possible. Long database transactions will prevent your application from scaling to a highly
concurrent load. It is not recommended that you hold a database transaction open during user
think time until the unit of work is complete.

What is the scope of a unit of work? Can a single Hibernate Session span several database
transactions, or is this a one-to-one relationship of scopes? When should you open and close
a Session and how do you demarcate the database transaction boundaries? These questions are
addressed in the following sections.

11.1.1. Unit of work

First, let's define a unit of work. A unit of work is a design pattern described by Martin Fowler as
“ [maintaining] a list of objects affected by a business transaction and coordinates the writing out
of changes and the resolution of concurrency problems. ”[PoEAA] In other words, its a series of
operations we wish to carry out against the database together. Basically, it is a transaction,
though fulfilling a unit of work will often span multiple physical database transactions
(see Section 11.1.2, “Long conversations”). So really we are talking about a more abstract notion
of a transaction. The term "business transaction" is also sometimes used in lieu of unit of work.

Do not use the session-per-operation antipattern: do not open and close a Session for every
simple database call in a single thread. The same is true for database transactions. Database calls
in an application are made using a planned sequence; they are grouped into atomic units of work.
This also means that auto-commit after every single SQL statement is useless in an application as
this mode is intended for ad-hoc SQL console work. Hibernate disables, or expects the
application server to disable, auto-commit mode immediately. Database transactions are never
optional. All communication with a database has to occur inside a transaction. Auto-commit
behavior for reading data should be avoided, as many small transactions are unlikely to perform
better than one clearly defined unit of work. The latter is also more maintainable and extensible.

The most common pattern in a multi-user client/server application is session-per-request. In this


model, a request from the client is sent to the server, where the Hibernate persistence layer runs.
A new Hibernate Session is opened, and all database operations are executed in this unit of work.
On completion of the work, and once the response for the client has been prepared, the session is
flushed and closed. Use a single database transaction to serve the clients request, starting and
committing it when you open and close the Session. The relationship between the two is one-to-
one and this model is a perfect fit for many applications.

The challenge lies in the implementation. Hibernate provides built-in management of the
"current session" to simplify this pattern. Start a transaction when a server request has to be
processed, and end the transaction before the response is sent to the client. Common solutions
are ServletFilter, AOP interceptor with a pointcut on the service methods, or a proxy/interception
container. An EJB container is a standardized way to implement cross-cutting aspects such as
transaction demarcation on EJB session beans, declaratively with CMT. If you use programmatic
transaction demarcation, for ease of use and code portability use the Hibernate Transaction API
shown later in this chapter.

Your application code can access a "current session" to process the request by
calling sessionFactory.getCurrentSession(). You will always get a Session scoped to the current
database transaction. This has to be configured for either resource-local or JTA environments,
see Section 2.5, “Contextual sessions”.

You can extend the scope of a Session and database transaction until the "view has been
rendered". This is especially useful in servlet applications that utilize a separate rendering phase
after the request has been processed. Extending the database transaction until view rendering, is
achieved by implementing your own interceptor. However, this will be difficult if you rely on
EJBs with container-managed transactions. A transaction will be completed when an EJB method
returns, before rendering of any view can start. See the Hibernate website and forum for tips and
examples relating to this Open Session in View pattern.

11.1.2. Long conversations

The session-per-request pattern is not the only way of designing units of work. Many business
processes require a whole series of interactions with the user that are interleaved with database
accesses. In web and enterprise applications, it is not acceptable for a database transaction to
span a user interaction. Consider the following example:

o The first screen of a dialog opens. The data seen by the user has been loaded in a
particular Session and database transaction. The user is free to modify the objects.
o The user clicks "Save" after 5 minutes and expects their modifications to be made
persistent. The user also expects that they were the only person editing this information
and that no conflicting modification has occurred.
From the point of view of the user, we call this unit of work a long-
running conversation or application transaction. There are many ways to implement this in your
application.

A first naive implementation might keep the Session and database transaction open during user
think time, with locks held in the database to prevent concurrent modification and to guarantee
isolation and atomicity. This is an anti-pattern, since lock contention would not allow the
application to scale with the number of concurrent users.

You have to use several database transactions to implement the conversation. In this case,
maintaining isolation of business processes becomes the partial responsibility of the application
tier. A single conversation usually spans several database transactions. It will be atomic if only
one of these database transactions (the last one) stores the updated data. All others simply read
data (for example, in a wizard-style dialog spanning several request/response cycles). This is
easier to implement than it might sound, especially if you utilize some of Hibernate's features:

o Automatic Versioning: Hibernate can perform automatic optimistic concurrency control


for you. It can automatically detect if a concurrent modification occurred during user
think time. Check for this at the end of the conversation.
o Detached Objects: if you decide to use the session-per-request pattern, all loaded
instances will be in the detached state during user think time. Hibernate allows you to
reattach the objects and persist the modifications. The pattern is called session-per-
request-with-detached-objects. Automatic versioning is used to isolate concurrent
modifications.
o Extended (or Long) Session: the Hibernate Session can be disconnected from the
underlying JDBC connection after the database transaction has been committed and
reconnected when a new client request occurs. This pattern is known as session-per-
conversation and makes even reattachment unnecessary. Automatic versioning is used to
isolate concurrent modifications and the Session will not be allowed to be flushed
automatically, but explicitly.

Both session-per-request-with-detached-objects and session-per-conversation have advantages


and disadvantages. These disadvantages are discussed later in this chapter in the context of
optimistic concurrency control.

11.1.3. Considering object identity

An application can concurrently access the same persistent state in two different Sessions.
However, an instance of a persistent class is never shared between two Session instances. It is for
this reason that there are two different notions of identity:

Database Identity

foo.getId().equals( bar.getId() )

JVM Identity
foo==bar

For objects attached to a particular Session (i.e., in the scope of a Session), the two
notions are equivalent and JVM identity for database identity is guaranteed by
Hibernate. While the application might concurrently access the "same" (persistent
identity) business object in two different sessions, the two instances will actually be
"different" (JVM identity). Conflicts are resolved using an optimistic approach and
automatic versioning at flush/commit time.

This approach leaves Hibernate and the database to worry about concurrency. It also
provides the best scalability, since guaranteeing identity in single-threaded units of
work means that it does not need expensive locking or other means of synchronization.
The application does not need to synchronize on any business object, as long as it
maintains a single thread per Session. Within a Session the application can safely
use == to compare objects.

However, an application that uses == outside of a Session might produce unexpected


results. This might occur even in some unexpected places. For example, if you put two
detached instances into the same Set, both might have the same database identity (i.e.,
they represent the same row). JVM identity, however, is by definition not guaranteed
for instances in a detached state. The developer has to override
the equals() and hashCode() methods in persistent classes and implement their own
notion of object equality. There is one caveat: never use the database identifier to
implement equality. Use a business key that is a combination of unique, usually
immutable, attributes. The database identifier will change if a transient object is made
persistent. If the transient instance (usually together with detached instances) is held in
a Set, changing the hashcode breaks the contract of the Set. Attributes for business
keys do not have to be as stable as database primary keys; you only have to guarantee
stability as long as the objects are in the same Set. See the Hibernate website for a
more thorough discussion of this issue. Please note that this is not a Hibernate issue,
but simply how Java object identity and equality has to be implemented.

11.1.4. Common issues

Do not use the anti-patterns session-per-user-session or session-per-application (there


are, however, rare exceptions to this rule). Some of the following issues might also
arise within the recommended patterns, so ensure that you understand the implications
before making a design decision:

o A Session is not thread-safe. Things that work concurrently, like HTTP


requests, session beans, or Swing workers, will cause race conditions if
a Session instance is shared. If you keep your Hibernate Session in
your HttpSession (this is discussed later in the chapter), you should consider
synchronizing access to your Http session. Otherwise, a user that clicks reload
fast enough can use the same Session in two concurrently running threads.
o An exception thrown by Hibernate means you have to rollback your database
transaction and close the Session immediately (this is discussed in more detail
later in the chapter). If your Session is bound to the application, you have to
stop the application. Rolling back the database transaction does not put your
business objects back into the state they were at the start of the transaction. This
means that the database state and the business objects will be out of sync.
Usually this is not a problem, because exceptions are not recoverable and you
will have to start over after rollback anyway.
o The Session caches every object that is in a persistent state (watched and
checked for dirty state by Hibernate). If you keep it open for a long time or
simply load too much data, it will grow endlessly until you get an
OutOfMemoryException. One solution is to call clear() and evict() to manage
the Session cache, but you should consider a Stored Procedure if you need mass
data operations. Some solutions are shown in Chapter 13, Batch processing.
Keeping a Session open for the duration of a user session also means a higher
probability of stale data.
11.2. Database transaction demarcation

Database, or system, transaction boundaries are always necessary. No communication


with the database can occur outside of a database transaction (this seems to confuse
many developers who are used to the auto-commit mode). Always use clear transaction
boundaries, even for read-only operations. Depending on your isolation level and
database capabilities this might not be required, but there is no downside if you always
demarcate transactions explicitly. Certainly, a single database transaction is going to
perform better than many small transactions, even for reading data.

A Hibernate application can run in non-managed (i.e., standalone, simple Web- or


Swing applications) and managed J2EE environments. In a non-managed environment,
Hibernate is usually responsible for its own database connection pool. The application
developer has to manually set transaction boundaries (begin, commit, or rollback
database transactions) themselves. A managed environment usually provides container-
managed transactions (CMT), with the transaction assembly defined declaratively (in
deployment descriptors of EJB session beans, for example). Programmatic transaction
demarcation is then no longer necessary.

However, it is often desirable to keep your persistence layer portable between non-
managed resource-local environments, and systems that can rely on JTA but use BMT
instead of CMT. In both cases use programmatic transaction demarcation. Hibernate
offers a wrapper API called Transaction that translates into the native transaction
system of your deployment environment. This API is actually optional, but we strongly
encourage its use unless you are in a CMT session bean.

Ending a Session usually involves four distinct phases:

o flush the session


o commit the transaction
o close the session
o handle exceptions

We discussed Flushing the session earlier, so we will now have a closer look at
transaction demarcation and exception handling in both managed and non-managed
environments.

11.2.1. Non-managed environment

If a Hibernate persistence layer runs in a non-managed environment, database


connections are usually handled by simple (i.e., non-DataSource) connection pools
from which Hibernate obtains connections as needed. The session/transaction handling
idiom looks like this:

// Non-managed environment idiom


Session sess = factory.openSession();
Transaction tx = null;
try {
tx = sess.beginTransaction();

// do some work
...

tx.commit();
}
catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e; // or display error message
}
finally {
sess.close();
}

You do not have to flush() the Session explicitly: the call to commit() automatically
triggers the synchronization depending on the FlushMode for the session. A call
to close() marks the end of a session. The main implication of close() is that the JDBC
connection will be relinquished by the session. This Java code is portable and runs in
both non-managed and JTA environments.

As outlined earlier, a much more flexible solution is Hibernate's built-in "current


session" context management:

// Non-managed environment idiom with getCurrentSession()


try {
factory.getCurrentSession().beginTransaction();
// do some work
...

factory.getCurrentSession().getTransaction().commit();
}
catch (RuntimeException e) {
factory.getCurrentSession().getTransaction().rollback();
throw e; // or display error message
}

You will not see these code snippets in a regular application; fatal (system) exceptions
should always be caught at the "top". In other words, the code that executes Hibernate
calls in the persistence layer, and the code that handles RuntimeException (and usually
can only clean up and exit), are in different layers. The current context management by
Hibernate can significantly simplify this design by accessing a SessionFactory.
Exception handling is discussed later in this chapter.

You should select org.hibernate.transaction.JDBCTransactionFactory, which is the


default, and for the second example select "thread" as
your hibernate.current_session_context_class.

11.2.2. Using JTA

If your persistence layer runs in an application server (for example, behind EJB session
beans), every datasource connection obtained by Hibernate will automatically be part
of the global JTA transaction. You can also install a standalone JTA implementation
and use it without EJB. Hibernate offers two strategies for JTA integration.

If you use bean-managed transactions (BMT), Hibernate will tell the application server
to start and end a BMT transaction if you use the Transaction API. The transaction
management code is identical to the non-managed environment.

// BMT idiom
Session sess = factory.openSession();
Transaction tx = null;
try {
tx = sess.beginTransaction();

// do some work
...

tx.commit();
}
catch (RuntimeException e) {
if (tx != null) tx.rollback();
throw e; // or display error message
}
finally {
sess.close();
}

If you want to use a transaction-bound Session, that is,


the getCurrentSession() functionality for easy context propagation, use the
JTA UserTransaction API directly:

// BMT idiom with getCurrentSession()


try {
UserTransaction tx = (UserTransaction)new InitialContext()
.lookup("java:comp/UserTransaction");

tx.begin();

// Do some work on Session bound to transaction


factory.getCurrentSession().load(...);
factory.getCurrentSession().persist(...);

tx.commit();
}
catch (RuntimeException e) {
tx.rollback();
throw e; // or display error message
}

With CMT, transaction demarcation is completed in session bean deployment


descriptors, not programmatically. The code is reduced to:

// CMT idiom
Session sess = factory.getCurrentSession();

// do some work
...

In a CMT/EJB, even rollback happens automatically. An


unhandled RuntimeException thrown by a session bean method tells the container to
set the global transaction to rollback. You do not need to use the
Hibernate Transaction API at all with BMT or CMT, and you get automatic
propagation of the "current" Session bound to the transaction.
When configuring Hibernate's transaction factory,
choose org.hibernate.transaction.JTATransactionFactory if you use JTA directly
(BMT), and org.hibernate.transaction.CMTTransactionFactory in a CMT session bean.
Remember to also set hibernate.transaction.manager_lookup_class. Ensure that
your hibernate.current_session_context_class is either unset (backwards compatibility),
or is set to "jta".

The getCurrentSession() operation has one downside in a JTA environment. There is


one caveat to the use of after_statement connection release mode, which is then used
by default. Due to a limitation of the JTA spec, it is not possible for Hibernate to
automatically clean up any unclosed ScrollableResults or Iterator instances returned
by scroll() or iterate(). You must release the underlying database cursor by
calling ScrollableResults.close() or Hibernate.close(Iterator) explicitly from
a finally block. Most applications can easily avoid using scroll() or iterate() from the
JTA or CMT code.)

11.2.3. Exception handling

If the Session throws an exception, including any SQLException, immediately rollback


the database transaction, call Session.close() and discard the Session instance. Certain
methods of Session will not leave the session in a consistent state. No exception
thrown by Hibernate can be treated as recoverable. Ensure that the Session will be
closed by calling close() in a finally block.

The HibernateException, which wraps most of the errors that can occur in a Hibernate
persistence layer, is an unchecked exception. It was not in older versions of Hibernate.
In our opinion, we should not force the application developer to catch an unrecoverable
exception at a low layer. In most systems, unchecked and fatal exceptions are handled
in one of the first frames of the method call stack (i.e., in higher layers) and either an
error message is presented to the application user or some other appropriate action is
taken. Note that Hibernate might also throw other unchecked exceptions that are not
a HibernateException. These are not recoverable and appropriate action should be
taken.

Hibernate wraps SQLExceptions thrown while interacting with the database in


a JDBCException. In fact, Hibernate will attempt to convert the exception into a more
meaningful subclass of JDBCException. The underlying SQLException is always
available via JDBCException.getCause(). Hibernate converts the SQLException into
an appropriate JDBCException subclass using the SQLExceptionConverter attached to
the SessionFactory. By default, the SQLExceptionConverter is defined by the
configured dialect. However, it is also possible to plug in a custom implementation.
See the javadocs for the SQLExceptionConverterFactory class for details. The
standard JDBCException subtypes are:

o JDBCConnectionException: indicates an error with the underlying JDBC


communication.
o SQLGrammarException: indicates a grammar or syntax problem with the
issued SQL.
o ConstraintViolationException: indicates some form of integrity constraint
violation.
o LockAcquisitionException: indicates an error acquiring a lock level necessary
to perform the requested operation.
o GenericJDBCException: a generic exception which did not fall into any of the
other categories.
11.2.4. Transaction timeout

An important feature provided by a managed environment like EJB, that is never


provided for non-managed code, is transaction timeout. Transaction timeouts ensure
that no misbehaving transaction can indefinitely tie up resources while returning no
response to the user. Outside a managed (JTA) environment, Hibernate cannot fully
provide this functionality. However, Hibernate can at least control data access
operations, ensuring that database level deadlocks and queries with huge result sets are
limited by a defined timeout. In a managed environment, Hibernate can delegate
transaction timeout to JTA. This functionality is abstracted by the
Hibernate Transaction object.

Session sess = factory.openSession();


try {
//set transaction timeout to 3 seconds
sess.getTransaction().setTimeout(3);
sess.getTransaction().begin();

// do some work
...

sess.getTransaction().commit()
}
catch (RuntimeException e) {
sess.getTransaction().rollback();
throw e; // or display error message
}
finally {
sess.close();
}

setTimeout() cannot be called in a CMT bean, where transaction timeouts must be


defined declaratively.
11.3. Optimistic concurrency control

The only approach that is consistent with high concurrency and high scalability, is
optimistic concurrency control with versioning. Version checking uses version
numbers, or timestamps, to detect conflicting updates and to prevent lost updates.
Hibernate provides three possible approaches to writing application code that uses
optimistic concurrency. The use cases we discuss are in the context of long
conversations, but version checking also has the benefit of preventing lost updates in
single database transactions.

11.3.1. Application version checking

In an implementation without much help from Hibernate, each interaction with the
database occurs in a new Session and the developer is responsible for reloading all
persistent instances from the database before manipulating them. The application is
forced to carry out its own version checking to ensure conversation transaction
isolation. This approach is the least efficient in terms of database access. It is the
approach most similar to entity EJBs.

// foo is an instance loaded by a previous Session


session = factory.openSession();
Transaction t = session.beginTransaction();

int oldVersion = foo.getVersion();


session.load( foo, foo.getKey() ); // load the current state
if ( oldVersion != foo.getVersion() ) throw new StaleObjectStateException();
foo.setProperty("bar");

t.commit();
session.close();

The version property is mapped using <version>, and Hibernate will automatically
increment it during flush if the entity is dirty.

If you are operating in a low-data-concurrency environment, and do not require version


checking, you can use this approach and skip the version check. In this case, last
commit wins is the default strategy for long conversations. Be aware that this might
confuse the users of the application, as they might experience lost updates without
error messages or a chance to merge conflicting changes.

Manual version checking is only feasible in trivial circumstances and not practical for
most applications. Often not only single instances, but complete graphs of modified
objects, have to be checked. Hibernate offers automatic version checking with either an
extended Session or detached instances as the design paradigm.
11.3.2. Extended session and automatic versioning

A single Session instance and its persistent instances that are used for the whole
conversation are known as session-per-conversation. Hibernate checks instance
versions at flush time, throwing an exception if concurrent modification is detected. It
is up to the developer to catch and handle this exception. Common options are the
opportunity for the user to merge changes or to restart the business conversation with
non-stale data.

The Session is disconnected from any underlying JDBC connection when waiting for
user interaction. This approach is the most efficient in terms of database access. The
application does not version check or reattach detached instances, nor does it have to
reload instances in every database transaction.

// foo is an instance loaded earlier by the old session


Transaction t = session.beginTransaction(); // Obtain a new JDBC connection, start
transaction

foo.setProperty("bar");

session.flush(); // Only for last transaction in conversation


t.commit(); // Also return JDBC connection
session.close(); // Only for last transaction in conversation

The foo object knows which Session it was loaded in. Beginning a new database
transaction on an old session obtains a new connection and resumes the session.
Committing a database transaction disconnects a session from the JDBC connection
and returns the connection to the pool. After reconnection, to force a version check on
data you are not updating, you can call Session.lock() with LockMode.READ on any
objects that might have been updated by another transaction. You do not need to lock
any data that you are updating. Usually you would set FlushMode.MANUAL on an
extended Session, so that only the last database transaction cycle is allowed to actually
persist all modifications made in this conversation. Only this last database transaction
will include the flush() operation, and then close() the session to end the conversation.

This pattern is problematic if the Session is too big to be stored during user think time
(for example, an HttpSession should be kept as small as possible). As the Session is
also the first-level cache and contains all loaded objects, we can probably use this
strategy only for a few request/response cycles. Use a Session only for a single
conversation as it will soon have stale data.

Note
Earlier versions of Hibernate required explicit disconnection and reconnection of
a Session. These methods are deprecated, as beginning and ending a transaction has the
same effect.
Keep the disconnected Session close to the persistence layer. Use an EJB stateful
session bean to hold the Session in a three-tier environment. Do not transfer it to the
web layer, or even serialize it to a separate tier, to store it in the HttpSession.

The extended session pattern, or session-per-conversation, is more difficult to


implement with automatic current session context management. You need to supply
your own implementation of the CurrentSessionContext for this. See the Hibernate
Wiki for examples.

11.3.3. Detached objects and automatic versioning

Each interaction with the persistent store occurs in a new Session. However, the same
persistent instances are reused for each interaction with the database. The application
manipulates the state of detached instances originally loaded in another Session and
then reattaches them using Session.update(), Session.saveOrUpdate(),
or Session.merge().

// foo is an instance loaded by a previous Session


foo.setProperty("bar");
session = factory.openSession();
Transaction t = session.beginTransaction();
session.saveOrUpdate(foo); // Use merge() if "foo" might have been loaded already
t.commit();
session.close();

Again, Hibernate will check instance versions during flush, throwing an exception if
conflicting updates occurred.

You can also call lock() instead of update(), and use LockMode.READ (performing a
version check and bypassing all caches) if you are sure that the object has not been
modified.

11.3.4. Customizing automatic versioning

You can disable Hibernate's automatic version increment for particular properties and
collections by setting the optimistic-lock mapping attribute to false. Hibernate will then
no longer increment versions if the property is dirty.

Legacy database schemas are often static and cannot be modified. Or, other
applications might access the same database and will not know how to handle version
numbers or even timestamps. In both cases, versioning cannot rely on a particular
column in a table. To force a version check with a comparison of the state of all fields
in a row but without a version or timestamp property mapping, turn on optimistic-
lock="all" in the <class> mapping. This conceptually only works if Hibernate can
compare the old and the new state (i.e., if you use a single long Session and not
session-per-request-with-detached-objects).

Concurrent modification can be permitted in instances where the changes that have
been made do not overlap. If you set optimistic-lock="dirty" when mapping
the <class>, Hibernate will only compare dirty fields during flush.

In both cases, with dedicated version/timestamp columns or with a full/dirty field


comparison, Hibernate uses a single UPDATE statement, with an
appropriate WHERE clause, per entity to execute the version check and update the
information. If you use transitive persistence to cascade reattachment to associated
entities, Hibernate may execute unnecessary updates. This is usually not a problem,
but on update triggers in the database might be executed even when no changes have
been made to detached instances. You can customize this behavior by setting select-
before-update="true" in the <class> mapping, forcing Hibernate to SELECT the
instance to ensure that changes did occur before updating the row.

11.4. Pessimistic locking

It is not intended that users spend much time worrying about locking strategies. It is
usually enough to specify an isolation level for the JDBC connections and then simply
let the database do all the work. However, advanced users may wish to obtain
exclusive pessimistic locks or re-obtain locks at the start of a new transaction.

Hibernate will always use the locking mechanism of the database; it never lock objects
in memory.

The LockMode class defines the different lock levels that can be acquired by
Hibernate. A lock is obtained by the following mechanisms:

o LockMode.WRITE is acquired automatically when Hibernate updates or inserts


a row.
o LockMode.UPGRADE can be acquired upon explicit user request
using SELECT ... FOR UPDATE on databases which support that syntax.
o LockMode.UPGRADE_NOWAIT can be acquired upon explicit user request
using a SELECT ... FOR UPDATE NOWAIT under Oracle.
o LockMode.READ is acquired automatically when Hibernate reads data under
Repeatable Read or Serializable isolation level. It can be re-acquired by explicit
user request.
o LockMode.NONE represents the absence of a lock. All objects switch to this
lock mode at the end of a Transaction. Objects associated with the session via a
call to update() or saveOrUpdate() also start out in this lock mode.

The "explicit user request" is expressed in one of the following ways:

o A call to Session.load(), specifying a LockMode.


o A call to Session.lock().
o A call to Query.setLockMode().

If Session.load() is called with UPGRADE or UPGRADE_NOWAIT, and the


requested object was not yet loaded by the session, the object is loaded
using SELECT ... FOR UPDATE. If load() is called for an object that is already loaded
with a less restrictive lock than the one requested, Hibernate calls lock() for that object.

Session.lock() performs a version number check if the specified lock mode


is READ, UPGRADE or UPGRADE_NOWAIT. In the case
of UPGRADE or UPGRADE_NOWAIT, SELECT ... FOR UPDATE is used.

If the requested lock mode is not supported by the database, Hibernate uses an
appropriate alternate mode instead of throwing an exception. This ensures that
applications are portable.

11.5. Connection release modes

One of the legacies of Hibernate 2.x JDBC connection management meant that
a Session would obtain a connection when it was first required and then maintain that
connection until the session was closed. Hibernate 3.x introduced the notion of
connection release modes that would instruct a session how to handle its JDBC
connections. The following discussion is pertinent only to connections provided
through a configured ConnectionProvider. User-supplied connections are outside the
breadth of this discussion. The different release modes are identified by the enumerated
values of org.hibernate.ConnectionReleaseMode:

o ON_CLOSE: is the legacy behavior described above. The Hibernate session


obtains a connection when it first needs to perform some JDBC access and
maintains that connection until the session is closed.
o AFTER_TRANSACTION: releases connections after
a org.hibernate.Transaction has been completed.
o AFTER_STATEMENT (also referred to as aggressive release): releases
connections after every statement execution. This aggressive releasing is
skipped if that statement leaves open resources associated with the given
session. Currently the only situation where this occurs is through the use
of org.hibernate.ScrollableResults.

The configuration parameter hibernate.connection.release_mode is used to specify


which release mode to use. The possible values are as follows:

o auto (the default): this choice delegates to the release mode returned by
the org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode() met
hod. For JTATransactionFactory, this returns
ConnectionReleaseMode.AFTER_STATEMENT; for JDBCTransactionFactory,
this returns ConnectionReleaseMode.AFTER_TRANSACTION. Do not
change this default behavior as failures due to the value of this setting tend to
indicate bugs and/or invalid assumptions in user code.
o on_close: uses ConnectionReleaseMode.ON_CLOSE. This setting is left for
backwards compatibility, but its use is discouraged.
o after_transaction: uses ConnectionReleaseMode.AFTER_TRANSACTION.
This setting should not be used in JTA environments. Also note that with
ConnectionReleaseMode.AFTER_TRANSACTION, if a session is considered
to be in auto-commit mode, connections will be released as if the release mode
were AFTER_STATEMENT.
o after_statement: uses ConnectionReleaseMode.AFTER_STATEMENT.
Additionally, the configured ConnectionProvider is consulted to see if it
supports this setting (supportsAggressiveRelease()). If not, the release mode is
reset to ConnectionReleaseMode.AFTER_TRANSACTION. This setting is
only safe in environments where we can either re-acquire the same underlying
JDBC connection each time you make a call
into ConnectionProvider.getConnection() or in auto-commit environments
where it does not matter if we re-establish the same connection.

Spring Controller – Spring MVC Controller

Spring Controller annotation is a specialization of @Component annotation. Spring Controller


annotation is typically used in combination with annotated handler methods based on the
RequestMapping annotation.

Spring Controller

Spring Controller annotation can be applied on classes only. It’s used to mark a class as a web
request handler. It’s mostly used with Spring MVC application.

Spring RestController

Spring @RestController is a convenience annotation that is itself annotated with @Controller


and @ResponseBody. This annotation is used to mark a class as request handler
for RESTful web services.
Spring Controller Example

Let’s create a simple spring application where we will implement standard MVC controller as
well as REST controller.

Create a “Dynamic Web Project” in Eclipse and then convert it to Maven project. This will
provide us with maven based web application structure and we can build our application on top
of it.

Below image shows the final project structure of our Spring MVC Controller application.

We would need following dependencies for our application.


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>

<!-- Jackson for REST -->


<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
Let’s look at the deployment descriptor (web.xml) where we will
configure DispatcherServlet servlet as the front controller.

<?xml version="1.0" encoding="UTF-8"?>


<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Spring-Controller</display-name>
<!-- Add Spring MVC DispatcherServlet as front controller -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Finally, we have following spring context file. Here we are configuring our application to be
annotation-based and providing root package for scanning spring components. We are also
configuring InternalResourceViewResolver bean and providing details of view pages.

<?xml version="1.0" encoding="UTF-8"?>


<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- Enables the Spring MVC @Controller programming model -->


<annotation-driven />

<context:component-scan base-package="com.journaldev.spring" />

<!-- Resolves views selected for rendering by @Controllers to JSP resources


in the /WEB-INF/views directory -->
<beans:bean

class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>

</beans:beans>

Our configuration XML files are ready, let’s move on to the Controller class now.

package com.journaldev.spring.controller;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {
@GetMapping("/hello")
public String home(Locale locale, Model model) {
Date date = new Date();
DateFormat dateFormat =
DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate);
return "home";
}

We have defined a single request handler method, it’s accepting GET requests with URI “/hello”
and returning “home.jsp” page as the response. Notice that we are setting an attribute to the
model, which will be used in the home.jsp page.

Here is our simple home.jsp page code.

<%@ page language="java" contentType="text/html; charset=UTF-8"


pageEncoding="UTF-8"%>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Hello world!</h1>

<p>The time on the server is ${serverTime}.</p>

</body>
</html>

Spring MVC Controller Test

Our conventional servlet based Spring MVC application with a simple controller is ready, just
export it as the WAR file and deploy on Tomcat or any other servlet container.

Then go to URL http://localhost:8080/Spring-Controller/hello and you should see the following


screen as output.
Spring Rest Controller Example (Developing simple applications)

Now let’s extend our application to expose REST APIs too. Create a model class that will be sent
as JSON response.

package com.journaldev.spring.model;

public class Person {

private String name;

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

Here is our simple REST Controller class.

package com.journaldev.spring.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.journaldev.spring.model.Person;

@RestController
public class PersonRESTController {

@RequestMapping("/rest")
public String healthCheck() {
return "OK";
}

@RequestMapping("/rest/person/get")
public Person getPerson(@RequestParam(name = "name", required = false,
defaultValue = "Unknown") String name) {
Person person = new Person();
person.setName(name);
return person;
}

Redeploy the application again to test our REST APIs.

Spring REST Controller Test

Go to URL http://localhost:8080/Spring-Controller/rest and you should get following output.

Go to URL http://localhost:8080/Spring-Controller/rest/person/get and you will get following


JSON response:
Now let’s provide the name parameter value in the URL, go to http://localhost:8080/Spring-
Controller/rest/person/get?name=Pankaj and you will get following JSON response.

You might also like