Implementation of tomcat clustering

  1. Installation of JDK
  2. Installation Apache web server
  3. Installation Tomcat
  4. Edit Tomcat server.xml
  5. Tomcat web.xml add <distributed /> in WEB-INF
  6. Install mod_jk Connector in module
  7. Edit in httpd.conf
  8. worker.properties file in conf
  9. mod_jk.log file in log
  10. Restart of Apache and Tomcat
  11. Test run Jsp & load balancing

Steps:

1) Installation of Jdk

Java can be downloaded from sun and installed.

Sun provides different executable file for Windows and Linux operating system version. Sun provide JDK for Linux in .bin or tar.gz format, and for Windows .exe format.

After downloading file from sun, install JDK simple double click or through command prompt.

2) Installation of apache web server for load balancing and load sharing

Download apache and install on same system for vertical tomcat clustering.

After installation of apache, we need to do some configuration

3) Installation of tomcat

Make three copy of tomcat If want to make three tomcat clustering system then need three copies of tomcat
Cluster 1 tomcatA
Cluster 2 tomcatB
Cluster 3 tomcatC

Horizontal Clustering

Vertical Clustering

If need three cluster then need to make three instance of tomcat

Installation is simple as we install tomcat normally. In this tomcat clustering we are going for vertical tomcat clustering. So all tomcat instance is in single server. If you want (real world clustering) that is also much simpler. Then work with ip instead of localhost, I am also including examples for download

4) Tomcat server.xml configuration

  1. Vertical tomcat clustering( on single machine)
  2. Horizontal tomcat clustering( on multiple machine)

Vertical tomcat clustering example

open Tomcat -> Conf -> server.xml

Edit highlighted and can give port which we can required

1 First tomcatA

<strong> </strong>
<div>

<!-- Note:  A  "Server" is not itself a  "Container", so you may not
 define  subcomponents such as "Valves" at this level.
 Documentation at  /docs/config/server.html
 -->
 <Server <strong>port="8105"</strong> shutdown="SHUTDOWN">

<!--APR library  loader. Documentation at /docs/apr.html  -->
 <Listener   className="org.apache.catalina.core.AprLifecycleListener"   SSLEngine="on" />
 <!--Initialize  Jasper prior to webapps are loaded. Documentation  at /docs/jasper-howto.html  -->
 <Listener  className="org.apache.catalina.core.JasperListener"  />
 <!-- JMX Support  for the Tomcat server. Documentation at  /docs/non-existent.html -->
 <Listener   className="org.apache.catalina.mbeans.ServerLifecycleListener" />
 <Listener   className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"   />

<!-- Global JNDI  resources
 Documentation  at /docs/jndi-resources-howto.html
 -->
 <GlobalNamingResources>
 <!-- Editable  user database that can also be used by
 UserDatabaseRealm to authenticate users
 -->
 <Resource  name="UserDatabase" auth="Container"
 type="org.apache.catalina.UserDatabase"
 description="User database that can be updated and  saved"
 factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
 pathname="conf/tomcat-users.xml" />
 </GlobalNamingResources>

<!-- A  "Service" is a collection of one or more  "Connectors" that  share
 a single  "Container" Note:  A  "Service" is not itself a  "Container",
 so you may not  define subcomponents such as "Valves" at this  level.
 Documentation  at /docs/config/service.html
 -->
 <Service  name="Catalina">

 <!--The  connectors can use a shared executor, you can define  one or more named thread  pools-->
 <!--
 <Executor  name="tomcatThreadPool" namePrefix="catalina-exec-"
 maxThreads="150"  minSpareThreads="4"/>
 -->

 <!-- A  "Connector" represents an endpoint by which requests  are received
 and responses  are returned. Documentation at :
 Java HTTP  Connector: /docs/config/http.html (blocking &  non-blocking)
 Java AJP  Connector: /docs/config/ajp.html
 APR  (HTTP/AJP) Connector: /docs/apr.html
 Define a  non-SSL HTTP/1.1 Connector on port 8080
 -->
 <Connector <strong>port="8081"</strong>  protocol="HTTP/1.1"
 connectionTimeout="20000"
 redirectPort="8443" />
 <!-- A  "Connector" using the shared thread pool-->
 <!--
 <Connector  executor="tomcatThreadPool"
 port="8080" protocol="HTTP/1.1"
 connectionTimeout="20000"
 redirectPort="8443" />
 -->
 <!-- Define a  SSL HTTP/1.1 Connector on port 8443
 This  connector uses the JSSE configuration, when using APR,  the
 connector  should be using the OpenSSL style configuration
 described in  the APR documentation -->
 <!--
 <Connector  port="8443" protocol="HTTP/1.1" SSLEnabled="true"
 maxThreads="150" scheme="https"  secure="true"
 clientAuth="false" sslProtocol="TLS" />
 -->

<!-- Define an  AJP 1.3 Connector on port 8009 -->
 <Connector <span style="color: #ff0000;">port="8109"</span> protocol="AJP/1.3" redirectPort="8443" />

&nbsp;

<!-- An Engine  represents the entry point (within  Catalina) that processes
 every  request.  The Engine implementation for  Tomcat stand  alone
 analyzes the HTTP headers included with  the request, and  passes them
 on to the  appropriate Host (virtual host).
 Documentation  at /docs/config/engine.html -->

<!-- You should  set jvmRoute to support load-balancing  via AJP ie :
 <Engine  name="Standalone" defaultHost="localhost"   jvmRoute="jvm1">
 -->
 <Engine  name="Catalina" defaultHost="localhost" <strong>jvmRoute="tomcatA"</strong>>

<!--For  clustering, please take a look at documentation  at:
 /docs/cluster-howto.html  (simple  how to)
 /docs/config/cluster.html (reference documentation) -->

 <strong><Cluster   className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/></strong>

<!-- The  request dumper valve dumps useful debugging  information about
 the request  and response data received and sent by Tomcat.
 Documentation at: /docs/config/valve.html -->
 <!--
 <Valve   className="org.apache.catalina.valves.RequestDumperValve"/>
 -->

<!-- This  Realm uses the UserDatabase configured in the  global JNDI
 resources  under the key "UserDatabase".   Any edits
 that are  performed against this UserDatabase are  immediately
 available  for use by the Realm.  -->
 <Realm   className="org.apache.catalina.realm.UserDatabaseRealm"
 resourceName="UserDatabase"/>

<!-- Define  the default virtual host
 Note: XML  Schema validation will not work with Xerces 2.2.
 -->
 <Host  name="localhost"   appBase="webapps"
 unpackWARs="true" autoDeploy="true"
 xmlValidation="false" xmlNamespaceAware="false">

<!--  SingleSignOn valve, share authentication between  web applications
 Documentation at: /docs/config/valve.html -->
 <!--
 <Valve   className="org.apache.catalina.authenticator.SingleSignOn" />
 -->

<!-- Access  log processes all example.
 Documentation at: /docs/config/valve.html -->
 <!--
 <Valve   className="org.apache.catalina.valves.AccessLogValve"  directory="logs"
 prefix="localhost_access_log." suffix=".txt"   pattern="common" resolveHosts="false"/>
 -->

</Host>
 </Engine>
 </Service>
 </Server>

</div>

2 Second tomcatB

<div>

<!-- Note:  A  "Server" is not itself a  "Container", so you may not
 define  subcomponents such as "Valves" at this level.
 Documentation at  /docs/config/server.html
 -->
 <Server <strong>port="8205"</strong> shutdown="SHUTDOWN">

<!--APR library  loader. Documentation at /docs/apr.html  -->
 <Listener   className="org.apache.catalina.core.AprLifecycleListener"   SSLEngine="on" />
 <!--Initialize  Jasper prior to webapps are loaded. Documentation  at /docs/jasper-howto.html  -->
 <Listener  className="org.apache.catalina.core.JasperListener"  />
 <!-- JMX Support  for the Tomcat server. Documentation at  /docs/non-existent.html -->
 <Listener   className="org.apache.catalina.mbeans.ServerLifecycleListener" />
 <Listener   className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"   />

<!-- Global JNDI  resources
 Documentation  at /docs/jndi-resources-howto.html
 -->
 <GlobalNamingResources>
 <!-- Editable  user database that can also be used by
 UserDatabaseRealm to authenticate users
 -->
 <Resource  name="UserDatabase" auth="Container"
 type="org.apache.catalina.UserDatabase"
 description="User database that can be updated and  saved"
 factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
 pathname="conf/tomcat-users.xml" />
 </GlobalNamingResources>

<!-- A  "Service" is a collection of one or more  "Connectors" that  share
 a single  "Container" Note:  A  "Service" is not itself a  "Container",
 so you may not  define subcomponents such as "Valves" at this  level.
 Documentation  at /docs/config/service.html
 -->
 <Service  name="Catalina">

 <!--The  connectors can use a shared executor, you can define  one or more named thread  pools-->
 <!--
 <Executor  name="tomcatThreadPool" namePrefix="catalina-exec-"
 maxThreads="150"  minSpareThreads="4"/>
 -->

 <!-- A  "Connector" represents an endpoint by which requests  are received
 and responses  are returned. Documentation at :
 Java HTTP  Connector: /docs/config/http.html (blocking &  non-blocking)
 Java AJP  Connector: /docs/config/ajp.html
 APR  (HTTP/AJP) Connector: /docs/apr.html
 Define a  non-SSL HTTP/1.1 Connector on port 8080
 -->
 <Connector <strong>port="8082"</strong> protocol="HTTP/1.1"
 connectionTimeout="20000"
 redirectPort="8443" />
 <!-- A  "Connector" using the shared thread pool-->
 <!--
 <Connector  executor="tomcatThreadPool"
 port="8080" protocol="HTTP/1.1"
 connectionTimeout="20000"
 redirectPort="8443" />
 -->
 <!-- Define a  SSL HTTP/1.1 Connector on port 8443
 This  connector uses the JSSE configuration, when using APR,  the
 connector  should be using the OpenSSL style configuration
 described in  the APR documentation -->
 <!--
 <Connector  port="8443" protocol="HTTP/1.1" SSLEnabled="true"
 maxThreads="150" scheme="https"  secure="true"
 clientAuth="false" sslProtocol="TLS" />
 -->

<!-- Define an  AJP 1.3 Connector on port 8009 -->
 <Connector <strong>port="8209"</strong> protocol="AJP/1.3" redirectPort="8443" />

&nbsp;

<!-- An Engine  represents the entry point (within  Catalina) that processes
 every  request.  The Engine implementation for  Tomcat stand  alone
 analyzes the HTTP headers included with  the request, and  passes them
 on to the  appropriate Host (virtual host).
 Documentation  at /docs/config/engine.html -->

<!-- You should  set jvmRoute to support load-balancing  via AJP ie :
 <Engine  name="Standalone" defaultHost="localhost"   jvmRoute="jvm1">
 -->
 <Engine  name="Catalina" defaultHost="localhost" <strong>jvmRoute="tomcatB"</strong>>

<!--For  clustering, please take a look at documentation  at:
 /docs/cluster-howto.html  (simple  how to)
 /docs/config/cluster.html (reference documentation) -->

<strong><Cluster   className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/></strong>

<!-- The  request dumper valve dumps useful debugging  information about
 the request  and response data received and sent by Tomcat.
 Documentation at: /docs/config/valve.html -->
 <!--
 <Valve   className="org.apache.catalina.valves.RequestDumperValve"/>
 -->

<!-- This  Realm uses the UserDatabase configured in the  global JNDI
 resources  under the key "UserDatabase".   Any edits
 that are  performed against this UserDatabase are  immediately
 available  for use by the Realm.  -->
 <Realm   className="org.apache.catalina.realm.UserDatabaseRealm"
 resourceName="UserDatabase"/>

<!-- Define  the default virtual host
 Note: XML  Schema validation will not work with Xerces 2.2.
 -->
 <Host  name="localhost"   appBase="webapps"
 unpackWARs="true" autoDeploy="true"
 xmlValidation="false" xmlNamespaceAware="false">

<!--  SingleSignOn valve, share authentication between  web applications
 Documentation at: /docs/config/valve.html -->
 <!--
 <Valve   className="org.apache.catalina.authenticator.SingleSignOn" />
 -->

<!-- Access  log processes all example.
 Documentation at: /docs/config/valve.html -->
 <!--
 <Valve   className="org.apache.catalina.valves.AccessLogValve"  directory="logs"
 prefix="localhost_access_log." suffix=".txt"   pattern="common" resolveHosts="false"/>
 -->

</Host>
 </Engine>
 </Service>
 </Server>

</div>

3 Third tomcatC

<strong></strong>
<div>

<!-- Note:  A  "Server" is not itself a  "Container", so you may not
 define  subcomponents such as "Valves" at this level.
 Documentation at  /docs/config/server.html
 -->
 <Server <strong>port="8305"</strong> shutdown="SHUTDOWN">

<!--APR library  loader. Documentation at /docs/apr.html  -->
 <Listener   className="org.apache.catalina.core.AprLifecycleListener"   SSLEngine="on" />
 <!--Initialize  Jasper prior to webapps are loaded. Documentation  at /docs/jasper-howto.html  -->
 <Listener  className="org.apache.catalina.core.JasperListener"  />
 <!-- JMX Support  for the Tomcat server. Documentation at  /docs/non-existent.html -->
 <Listener   className="org.apache.catalina.mbeans.ServerLifecycleListener" />
 <Listener   className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"   />

<!-- Global JNDI  resources
 Documentation  at /docs/jndi-resources-howto.html
 -->
 <GlobalNamingResources>
 <!-- Editable  user database that can also be used by
 UserDatabaseRealm to authenticate users
 -->
 <Resource  name="UserDatabase" auth="Container"
 type="org.apache.catalina.UserDatabase"
 description="User database that can be updated and  saved"
 factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
 pathname="conf/tomcat-users.xml" />
 </GlobalNamingResources>

<!-- A  "Service" is a collection of one or more  "Connectors" that  share
 a single  "Container" Note:  A  "Service" is not itself a  "Container",
 so you may not  define subcomponents such as "Valves" at this  level.
 Documentation  at /docs/config/service.html
 -->
 <Service  name="Catalina">

 <!--The  connectors can use a shared executor, you can define  one or more named thread  pools-->
 <!--
 <Executor  name="tomcatThreadPool" namePrefix="catalina-exec-"
 maxThreads="150"  minSpareThreads="4"/>
 -->

 <!-- A  "Connector" represents an endpoint by which requests  are received
 and responses  are returned. Documentation at :
 Java HTTP  Connector: /docs/config/http.html (blocking &  non-blocking)
 Java AJP  Connector: /docs/config/ajp.html
 APR  (HTTP/AJP) Connector: /docs/apr.html
 Define a  non-SSL HTTP/1.1 Connector on port 8080
 -->
 <Connector <strong>port="8083"</strong> protocol="HTTP/1.1"
 connectionTimeout="20000"
 redirectPort="8443" />
 <!-- A  "Connector" using the shared thread pool-->
 <!--
 <Connector  executor="tomcatThreadPool"
 port="8080" protocol="HTTP/1.1"
 connectionTimeout="20000"
 redirectPort="8443" />
 -->
 <!-- Define a  SSL HTTP/1.1 Connector on port 8443
 This  connector uses the JSSE configuration, when using APR,  the
 connector  should be using the OpenSSL style configuration
 described in  the APR documentation -->
 <!--
 <Connector  port="8443" protocol="HTTP/1.1" SSLEnabled="true"
 maxThreads="150" scheme="https"  secure="true"
 clientAuth="false" sslProtocol="TLS" />
 -->

<!-- Define an  AJP 1.3 Connector on port 8009 -->
 <Connector <strong>port="8309"</strong> protocol="AJP/1.3" redirectPort="8443" />

&nbsp;

<!-- An Engine  represents the entry point (within  Catalina) that processes
 every  request.  The Engine implementation for  Tomcat stand  alone
 analyzes the HTTP headers included with  the request, and  passes them
 on to the  appropriate Host (virtual host).
 Documentation  at /docs/config/engine.html -->

<!-- You should  set jvmRoute to support load-balancing  via AJP ie :
 <Engine  name="Standalone" defaultHost="localhost"   jvmRoute="jvm1">
 -->
 <Engine  name="Catalina" defaultHost="localhost" <strong>jvmRoute="tomcatC"</strong>>

<!--For  clustering, please take a look at documentation  at:
 /docs/cluster-howto.html  (simple  how to)
 /docs/config/cluster.html (reference documentation) -->

<strong><Cluster   className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/></strong>

<!-- The  request dumper valve dumps useful debugging  information about
 the request  and response data received and sent by Tomcat.
 Documentation at: /docs/config/valve.html -->
 <!--
 <Valve   className="org.apache.catalina.valves.RequestDumperValve"/>
 -->

<!-- This  Realm uses the UserDatabase configured in the  global JNDI
 resources  under the key "UserDatabase".   Any edits
 that are  performed against this UserDatabase are  immediately
 available  for use by the Realm.  -->
 <Realm   className="org.apache.catalina.realm.UserDatabaseRealm"
 resourceName="UserDatabase"/>

<!-- Define  the default virtual host
 Note: XML  Schema validation will not work with Xerces 2.2.
 -->
 <Host  name="localhost"   appBase="webapps"
 unpackWARs="true" autoDeploy="true"
 xmlValidation="false" xmlNamespaceAware="false">

<!--  SingleSignOn valve, share authentication between  web applications
 Documentation at: /docs/config/valve.html -->
 <!--
 <Valve   className="org.apache.catalina.authenticator.SingleSignOn" />
 -->

<!-- Access  log processes all example.
 Documentation at: /docs/config/valve.html -->
 <!--
 <Valve   className="org.apache.catalina.valves.AccessLogValve"  directory="logs"
 prefix="localhost_access_log." suffix=".txt"   pattern="common" resolveHosts="false"/>
 -->

</Host>
 </Engine>
 </Service>
 </Server>

</div>

4) Horizontal tomcat clustering or tomcat clustering on different machine system

If you want to do horizontal tomcat clustering then you don’t need to change in ports

Just left ports unchanged e.g
1. <Server port=”8005″ shutdown=”SHUTDOWN”>
2. <Connector port=”8080″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ />

3. <Connector port=”8009″ protocol=”AJP/1.3″ redirectPort=”8443″ />

4. Add jvmRoute

<Engine name=”Catalina” defaultHost=”localhost” jvmRoute=”tomcatC”>

5. Uncommented clustering tag

<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”/>

5) Add distributed tag in web.xml

Next step to do add distributed tag in web.xml to switching session among the tomcat clustering instance

Make any application, e.g we are making cluster as application folder in webapps

1. TomcatA – >  webapps – > cluster -> WEB-INF -> web.xml
2. TomcatB – >  webapps – > cluster -> WEB-INF -> web.xml
3. TomcatC – >  webapps – > cluster -> WEB-INF -> web.xml

Add  <distributable /> in all three web.xml file

<div>

<?xml version="1.0"  encoding="ISO-8859-1"?>

<web-app  xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 version="2.5">
<strong><distributable /></strong>

 </web-app>

</div>

6) Install mod_jk in module

Mod_jk is connector that communicates with apache web server and tomcat. We need to download and copy that connector in module folder of apache
http://tomcat.apache.org/connectors-doc/ we are using latest connector of mod_jk

Make mod_jk.log file in logs folder otherwise apache will throw error

7) Edit in httpd.conf

Open apache -> httpd.conf

Open in any text editor and add

LoadModule jk_module modules/mod_jk-apache-2.2.4.so
JkWorkersFile “C:\cluster\Apache\conf\workers.properties”
JkLogFile “logs/mod_jk.log”
JkLogLevel error
JkMount /cluster loadbalancer
JkMount /cluster/* loadbalancer

8 ) Worker.properties file

Make a file with name of workers.properties in conf folder. This file tells properties of all tomcat instances. We have to specify all tomcat properties here. Apache will forword request to tomcat through this file

Vertical tomcat clustering this file like

workers.tomcat_home=/tomcatA
workers.java_home=$JAVA_HOME
ps=/
worker.list=tomcatA,tomcatB,tomcatC,loadbalancer

worker.tomcatA.port=8109
worker.tomcatA.host=localhost
worker.tomcatA.type=ajp13
worker.tomcatA.lbfactor=1

worker.tomcatB.port=8209
worker.tomcatB.host=localhost
worker.tomcatB.type=ajp13
worker.tomcatB.lbfactor=1

worker.tomcatC.port=8309
worker.tomcatC.host=localhost
worker.tomcatC.type=ajp13
worker.tomcatC.lbfactor=1

worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tomcatA,tomcatB,tomcatC
worker.loadbalancer.sticky_session=1

for horizontal tomcat clustering

workers.tomcat_home=/tomcatA
workers.java_home=$JAVA_HOME
ps=/
worker.list=tomcatA,tomcatB,tomcatC,loadbalancer

worker.tomcatA.port=8009
worker.tomcatA.host=192.168.1.1
worker.tomcatA.type=ajp13
worker.tomcatA.lbfactor=1

worker.tomcatB.port=8009
worker.tomcatB.host=192.168.1.2
worker.tomcatB.type=ajp13
worker.tomcatB.lbfactor=1

worker.tomcatC.port=8009
worker.tomcatC.host=192.168.1.3
worker.tomcatC.type=ajp13
worker.tomcatC.lbfactor=1

worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tomcatA,tomcatB,tomcatC
worker.loadbalancer.sticky_session=1

bfactor properties define for load balancing factor, restrict number of  request to send particular tomcat instance
e.g
worker.tomcatC.lbfactor=100
increase and decrease request to this tomcatC instance

10) Restart apache, tomcatA, tomcatB, tomcatC

Check clustering if apache start properly, It is fine without any errors otherwise check problems,basically mod_jk problems come. So download different mod_jk for your machine. Start all tomcats, tomcatA, tomcatB, and tomcatC. If all tomcats is started this means tomcat is working fine.

Open test.jsp on browser and check session id. Check which tomcat on test.jsp is running tomcatB or tomcatC. Close that tomcat, reload test.jsp. Check session id,if session id is same. Then tomcat clustering is working fine.

11) Test jsp file

Make test.jsp in cluster folder of webapps

tomcatA

<div>

<%
 session.setAttribute("a","a");
 %>
 <html>
 <head>
 <title>Test  JSP</title>
 </head>

<body>
 <table  width="100%" border="0" cellspacing="0"   cellpadding="0">
 <tr bgcolor="#CCCCCC">
 <td width="13%">TomcatA  Machine</td>
 <td  width="87%">&nbsp;</td>
 </tr>
 <tr>
 <td>Session ID :</td>
 <td><%=session.getId()%></td>
 </tr>
 </table>
 </body>
 </html>

</div>

tomcatB


<%
 session.setAttribute("a","a");
 %>
 <html>
 <head>
 <title>Test  JSP</title>
 </head>

<body>
 <table  width="100%" border="0" cellspacing="0"   cellpadding="0">
 <tr bgcolor="#CCCC00">
 <td width="13%">TomcatB  Machine</td>
 <td  width="87%">&nbsp;</td>
 </tr>
 <tr>
 <td>Session ID :</td>
 <td><%=session.getId()%></td>
 </tr>
 </table>
 </body>

</html>

TomcatC


<%
 session.setAttribute("a","a");
 %>
 <html>
 <head>
 <title>Test JSP</title>
 </head>

<body>
 <table width="100%" border="0"  cellspacing="0" cellpadding="0">
 <tr  bgcolor="#00CCCC">
 <td  width="13%">TomcatC Machine</td>
 <td  width="87%">&nbsp;</td>
 </tr>
 <tr>
 <td>Session  ID :</td>
 <td><%=session.getId()%></td>
 </tr>
 </table>
 </body>

</html>


Life Cycle Management of a Spring Bean

1) Introduction

This article would brief about how a Spring Bean is managed in IOC (Inversion of Control) Container. Spring Beans exist within the Container as long as they are needed by the Appplication. There are various life-cycle interfaces and methods that will be called by the IOC Container.

2) Bean Life Cycle

A Spring Bean represents a POJO component performing some useful operation. All Spring Beans reside within a Spring Container also known as IOC Container. The Spring Framework is transparent and thereby hides most of the complex infrastructure and the communication that happens between the Spring Container and the Spring Beans. This section lists the sequence of activities that will take place between the time of Bean Instantiation and hand over of the Bean reference to the Client Application.

  1. The Bean Container finds the definition of the Spring Bean in the Configuration file.
  2. The Bean Container creates an instance of the Bean using Java Reflection API.
  3. If any properties are mentioned, then they are also applied. If the property itself is a Bean, then it is resolved and set.
  4. If the Bean class implements the BeanNameAware interface, then the setBeanName() method will be called by passing the name of the Bean.
  5. If the Bean class implements the BeanClassLoaderAware interface, then the method setBeanClassLoader() method will be called by passing an instance of the ClassLoader object that loaded this bean.
  6. If the Bean class implements the BeanFactoryAware interface, then the method setBeanFactory() will be called by passing an instance of BeanFactory object.
  7. If there are any BeanPostProcessors object associated with the BeanFactory that loaded the Bean, then the method postProcessBeforeInitialization() will be called even before the properties for the Bean are set.
  8. If the Bean class implements the InitializingBean interface, then the method afterPropertiesSet() will be called once all the Bean properties defined in the Configuration file are set.
  9. If the Bean definition in the Configuration file contains a 'init-method' attribute, then the value for the attribute will be resolved to a method name in the Bean class and that method will be called.
  10. The postProcessAfterInitialization() method will be called if there are any Bean Post Processors attached for the Bean Factory object.
  11. If the Bean class implements the DisposableBean interface, then the method destroy() will be called when the Application no longer needs the bean reference.
  12. If the Bean definition in the Configuration file contains a 'destroy-method' attribute, then the corresponding method definition in the Bean class will be called.

http://www.javabeat.net/articles/49-life-cycle-management-of-a-spring-bean-1.html


Request life cycle of Spring web applications

This post will analyse the request life cycle of Spring web applications with the codes of Spring Framework MVC application I did in lab.

1. Browser sends request, received by DispatcherServlet.

DispatcherServlet is set in war/WEB-INF/web.xml.

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

<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

All the reqests as the name of *.htm will be handled by springapp, which is a DispatcherServlet.

2. To figure which controller to use.

<bean id=”urlMapping”>
<property name=”mappings”>
<props>
<prop key=”/hello.htm”>springappController</prop>
<prop key=”/priceincrease.htm”>priceIncreaseForm</prop>
</props>
</property>
</bean>

This codes in war/WEB-INF/springapp-servlet.xml is mapping /hello.htm and /priceincrease.htm to 2 controllers separately.

3. Dispatcher server requests Controller, controller returns ModelAndView object.

In src/web/SpringappController.java

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

String now = (new java.util.Date()).toString();
logger.info(“returning hello view with ” + now);

Map myModel = new HashMap();
myModel.put(“now”, now);
myModel.put(“products”, getProductManager().getProducts());

return new ModelAndView(“hello”, “model”, myModel);
}

The controller returns a ModelAndView object whose viewName is “hello”, modelName is “model” and model object is a Map object named as myModel.

4. If ModelAndView contains logical name for a View, DispatcherServlet queries ViewResolver for the View object that will render the response.

<bean id=”viewResolver”>
<property name=”viewClass”>
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name=”prefix”><value>/WEB-INF/jsp/</value></property>
<property name=”suffix”><value>.jsp</value></property>
</bean>

This codes will add prfix and suffix to the viewName of ModelAndView object, in this example, hello will be fixed as /WEB-INF/jsp/hello.jsp .

5. DispatcherServlet requests the View Object. /WEB-INF/jsp/hello.jsp will be shown on browser.

Understanding Caching in Hibernate

Understanding Caching in Hibernate – Part One : The Session Cache

Hibernate offers caching functionality which is designed to reduces the amount of necessary database access.  This is a very powerful feature if used correctly. However I have seen a lot of cases and also talked to many people on caching in Hibernate, where caching is either not understood correctly or even used the wrong way.

There are already a number of good articles on Hibernate caching, which provide good hints on how to use the cache. The Hibernate documentation itself offers good advise. Still I see value in having a deeper look at the dynamic and behaviour of the Hibernate cache as it might help people to understand it even better.

Hibernate Cache Types

Hibernate uses different types of caches. Each type of cache is used for different purposes. Let us first have a look at this cache types.

  • The first cache type is the session cache. The session cache caches object within the current session.
  • The second cache type is the query Cache. The query cache is responsible for caching queries and their results.
  • The third cache type is the second level cache. The second level cache is responsible for caching objects across sessions.

Now as we have an overview of caching types we can look at them in more detail. We will use dynaTrace to provide detailed insight into the dynamic of Hibernate caching. In this post we will start looking closer at the session cache.

Sample Data Model

For the samples used in the post, we will use a very simple data model. Although it is simple it is sufficient for illustration purposes and you should not have any problems mapping it to your application’s use cases.

Our data model consists of two entities – Persons and Addresses. Persons have references to Addresses. This allows us to explore caching behaviour regarding single entities as well as relations.

The Session Cache

As already the session cache caches values within the current session.  This cache is enabled by default.  Let us have a look at the following code sample. We create two queries to load a person object from cache. As we are loading the same object twice, we expect it to be retrieved from the cache.

Session session = getSessionFactory().openSession();

Transaction tx = session.beginTransaction();

Query query = session.createQuery(“from Person p where p.id=1”);

Iterator it = query.list().iterator();

while (it.hasNext ()){

Person p = (Person) it.next();

System.out.println(p.getFirstName());

}

query = session.createQuery(“from Person p where p.id=1”);

it = query.list().iterator();

while (it.hasNext ()){

Person p = (Person) it.next();

System.out.println(p.getFirstName());

}

tx.commit();

session.close();

Using the code above we would expect the query to be executed only once. However if we look at the PurePath of this transaction we can see, that two database queries have been executed.

Loading a person two times in a row, but no session cache involved

Now we will not use the createQuery but instead the load Method and pass the key directly as shown in the code below. The System.out.println calls by the way are required to force Hibernate to load data at all. If we would not put them in, nothing would get loaded. This is because data is always by default loaded lazyly in Hibernate. Thoug interesting this if off topic for this post.

Session session = getSessionFactory().openSession();

Transaction tx = session.beginTransaction();

Person person1 = (Person) session.load(Person.class, 1L);

System.out.println(person1.getFirstName());

Person person2 = (Person) session.load(Person.class, 1L);

System.out.println(person2.getFirstName());

tx.commit();

session.close();

As we can see in the trace below, now only one database query is issued. The same behaviour could have been achieve by using get instead of load.  For more information on the difference between these two methos either refer to the Hibernate documentation or read this nice blog post(I have chosen one from may out there)

Loading by class and key using session cache

The question now is what is the difference between these two scenarios and why does it work in one case and not in the other. Therefore we have to look deeper into Hibernate to see what is going on the second example. As shown below Hibernate first tries to retrieve the object within the session, if this fails (like in the green section), the object will be loaded from the database.  The objects retrieval and storage in handled by the  _PersistenceContext_ object, which is kept by within the Hibernate session.

Difference First and Second Time Loading

The handling for storing objects in the persistence context is the same, whether we use the _load_ method or a hibernate query. The figure below shows the dynamic behavior for loading the object via a hibernate query. This however also means that all objects loaded within a session are kept as long this session is open. This can lead to performance problems due to memory consumption in cases where a large amount of objects are loaded.

Persistence Context Behavior When Using Hibernate Query

Conclusion

Hibernate internally always uses the session cache transparently.  We have also seen that Hibernate requires a key to load object from the session cache. So in case we have a key available it is prefered to use load and a key instead of a HQL query.

 

Understanding Caching in Hibernate – Part Two : The Query Cache

by Alois Reitbauer, Feb 16, 09

In the last post I wrote on caching in Hibernate in general as well as on the behavior of the session cache. In this post we will have a closer look at the QueryCache. I will not explain the query cache in details as there are very good articles like Hibernate: Truly Understanding the Second-Level and Query Caches.

As we have seen in the last post the session cache can help in caching values when we have an _EntityKey_ available. If we do not have the key, we ran into the problems of having to issue multiple queries for retrieving the same object. This was the reason why the session cache worked fine for the _load_ method but not when we used _session.createQuery()_.

Now this is the point where the query cache comes into play.  The query cache is responsible for caching the results of queries – or to be more precise the keys of the objects returned by queries.  Let us have a look how Hibernate uses the query cache to retrieve objects. In order to make use of the query cache we have to modify the person loading example as follows.

Session session = getSessionFactory().openSession();

Transaction tx = session.beginTransaction();

Query query = session.createQuery(“from Person p where p.id=1”);

query.setCacheable(true);

Iterator it = query.list().iterator();

while (it.hasNext ()){

Person p = (Person) it.next();

System.out.println(p.getFirstName());

}

query = session.createQuery(“from Person p where p.id=1”);

query.setCacheable(true);

it = query.list().iterator();

while (it.hasNext ()){

Person p = (Person) it.next();

System.out.println(p.getFirstName());

}

tx.commit();

session.close();

As highlighted in bold face we had to add a line for defining that the query is actually cachable. If we would not do this, it won’t be cached.  (Note: The while loops could be omitted here. I am using for other examples where we have multiple results. …. just for code esthetics lovers). Additionally we also have to change the hibernate configuration to enable the query cache. This is done by adding the following line to the Hibernate configuration.

<property name=”hibernate.cache.use_query_cache”>true</property>

Unlike most examples I found on the web I will not immediately enable the second-level cache. As the basic working do not depend on it and I do not want to create the impression that the query cache requires the second level or vice versa. Let us now verify that everything is working correctly. As we can see below only the first _query.list()_ result in a SQL statement to be issued.

Caching by the Query Cache For Two Susequent Queries

The question now is, what happens internally. Therefore we analyze what happens within the second _get_ method of the _StandardQueryCache_. As we can see in the image below Hibernate first tries to retrieve the key values from the cache (as we can see the query cache internally uses the _EhCache_). After retrieving the keys the person entity is loaded from the session cache.

Internal Behavior of the Hibernate Query Cache

Query Cache Pitfalls

The query cache can be really usefull to optimize the performance of your data access layer. However there are a number of pitfalls as well.  This blog post describes a serious problem regarding memory consumption of the Hibernate query cache when using objects as parameters.

Conclusion

We have learned that the query cache helps us to cache the keys of results of Hibernate queries. These keys are then used to retrieve data objects using the Hibernate Internal loading behavior which involves the session cache and potentially also the second-level cache.

 

Understanding Caching in Hibernate – Part Three : The Second Level Cache

by Alois Reitbauer, Mar 24, 09

In the last posts I already covered the session cache as well as the query cache. In this post I will focus on the second-level cache. The Hibernate Documentation provides a good entry point reading on the second-level cache.

The key characteristic of the second-level cache is that is is used across sessions, which also differentiates it from the session cache, which only – as the name says – has session scope. Hibernate provides a flexible concept to exchange cache providers for the second-level cache. By default Ehcache is used as caching provider. However more sophisticated caching implementation can be used like the distributed JBoss Cache or Oracle Coherence.

First we have to modify our code sample so that we now load the Person object in two sessions. The source code then looks as follows

public void loadInTwoSessions (){

// loading in first session

Session session = getSessionFactory().openSession();

Transaction tx = session.beginTransaction();

Person p = (Person) session.load(Person.class, 1L);

System.out.println(p.getFirstName());

tx.commit();

session.close();

// loading in second session

session = getSessionFactory().openSession();

tx = session.beginTransaction();

p = (Person) session.load(Person.class, 1L);

System.out.println(p.getFirstName());

tx.commit();

session.close();

}

As we have not activated the second level cache, we expect the SQL queries to be executed twice. Looking at the PurePath of this transactions verifies our asumption.

Loading a person object in two sessions without second-level cache

Now we activate the second-level cache. Activating the second level cache requires us change to Hibernate configuration file and enable second-level caching by adding and additionally specify the cache provider as shown below.

<property name=”hibernate.cache.use_second_level_cache”>true</property>

<property name=”hibernate.cache.provider_class”>org.hibernate.cache.EhCacheProvider</property>

In this example I am using Ehcache for demonstration purposes. In order to enable caching of our Person objects if have to specify the caching configuration in the ehcache.xml file.  The actual cache configuration depends on the caching provider. For Ehcache the configuartion is defined as follows. The configuration for the Person class used in the example is boiler-plate Ehcache configuration. It can be adopted to specific needs. Describing all possible configurations options like using mulitple cache regions etc. is beyond scope of this post.

<cache name=”com.dynatrace.samples.database.Person”

maxElementsInMemory=”300″

eternal=”true”

overflowToDisk=”false”

timeToIdleSeconds=”12000″

timeToLiveSeconds=”12000″

diskPersistent=”false”

diskExpiryThreadIntervalSeconds=”120″

memoryStoreEvictionPolicy=”LRU”

/>

Finally we have to configure caching also at Hibernate level. Hibernate supports mulitple settings for caching. As we are only reading data it the moment a read-only cache is sufficient for our purposes. Hibernate for sure supports  read-write cache as well and also transactional caches in case this is supported by the cache provider.  The following liine in the hibernate configuration enable read-only caching for Person objects. Alternatively also Hibernate associations could be used.

<cache usage=”read-only” />

Now we expect the object to be retrieved from the second-level the second time it is loaded. A PurePath trace verifies this assumption.  Now, only the first time a database call gets executed.

Loading a person object in two sessions with enabled second-level cache

Read-Write Caching

After having looked at plain read caching we look in the next step at read-write caching.  Our code example gets a bit more complex. We again use two sessions. We load the object in the first session, update it thenload it in the second session. Both sessions are created upfront and are kept open until the end.

public void complexLoad (){

Session session1 = getSessionFactory().openSession();

Session session2 = getSessionFactory().openSession();

Transaction tx1 = session1.beginTransaction();

Person p1 = (Person) session1.load(Person.class, 1L);

System.out.println (p1.getFirstName());

p1.setFirstName (“” + System.currentTimeMillis());

tx1.commit();

Transaction tx2 = session2.beginTransaction();

Person p2 = (Person)session2.load(Person.class, 1L);

System.out.println (p2.getFirstName());

tx2.commit();

session1.close();

session2.close();

}

We expect the object to be retrieved from the cache when it is loaded in the second session.  Looking at the PurePath of this transaction however shows something different. This method executes three SQL statements. First a SELECT to load the Person object, then an UPDATE to update the record in the database and then again a SELECT to load the Person object for the second session.

Two transaction loading a person object both times leading to a database query.

This is not what we necessarily where expecting. The object could have been retrieved from the cache in the second session. However it got loaded from the database. So why wasn’t the object taken from the cache. A closer look at the internal Hibernate behaviour unveils this secret.

Details on loading from second-level cache

The PurePath snippet above shows the details for loading the Person object in the second session. The key is the isGettable method, which in this case returns false. The input to isGettable is the session creation timestamp, as indicated by the arrow.  A look at the sourcecode unveils what is checked within this method.

public boolean isGettable(long txTimestamp) {

return freshTimestamp < txTimestamp;

}

The method verifies wheter the session’s timestamp (txTimestamp) is greated than the freshTimestamp of the cached object. In our case the second session was created BEFORE the object was updated. Consequently this method will return false. If we modify our code as follows the object will be loaded from the second-level cache.

public void complexLoad (){

Session session1 = getSessionFactory().openSession();

Transaction tx1 = session1.beginTransaction();

Person p1 = (Person) session1.load(Person.class, 1L);

System.out.println (p1.getFirstName());

p1.setFirstName (“” + System.currentTimeMillis());

tx1.commit();

Session session2 = getSessionFactory().openSession();

Transaction tx2 = session2.beginTransaction();

Person p2 = (Person)session2.load(Person.class, 1L);

System.out.println (p2.getFirstName());

tx2.commit();

session1.close();

session2.close();

}

The PurePath snipped below verfies this assumption and shows that this time isGettable returns true and the object is retrieved from the cache.

Loading the Person object from second-level cache directly

Interaction of Session and Second-Level Cache

Finally I want to take a short look of the interaction between the session and the second-level cache. The important point to understand is that as soon as we use the second-level cache we have two caches in place. Caches are always a source of inconsistent information, which we take as the price for better performance and scalability. In order to avoid problems and unwanted behaviour we have to understand their internal behaviour.  Hibernate always tries to first retrieve objects from the session and if this fails tries to retrieve them from the second-level cache. If this fails again objects are directly loaded from the database.  The PurePath snippet below shows this loading behavior.

Load hierarchy in Hibernate showing logical flow of object retrieval

Conclusion

The second level cache is powerful mechanism for improving performance and scalability of your database driven application. Read-only caches are easy to handle, while read-write caches are more subtile in their behavior. Especially the interaction with the Hibernate session can lead to unwanted behavior. Sessions should therefore be used as what they are designed for – a transactional context. There are more details on the second-level cache I did not elaborate on like synchronization or replication behavior. However the combination of the three caching articles should provide good insight into Hibernate caching behavior.

See Also

http://blog.dynatrace.com/tag/hibernate/

For Testing Tool:

http://blog.dynatrace.com/2009/11/17/a-step-by-step-guide-to-dynatrace-ajax-edition-available-today-for-public-download/

Hibernate Interview Questions

1.What is ORM ?

ORM stands for object/relational mapping. ORM is the automated persistence of objects in a Java application to the tables in a relational database.

2.What does ORM consists of ?

An ORM solution consists of the followig four pieces:

  • API for performing basic CRUD operations
  • API to express queries refering to classes
  • Facilities to specify metadata
  • Optimization facilities : dirty checking,lazy associations fetching

3.What are the ORM levels ?

The ORM levels are:

  • Pure relational (stored procedure.)
  • Light objects mapping (JDBC)
  • Medium object mapping
  • Full object Mapping (composition,inheritance, polymorphism, persistence by reachability)

4.What is Hibernate?

Hibernate is a pure Java object-relational mapping (ORM) and persistence framework that allows you to map plain old Java objects to relational database tables using (XML) configuration files.Its purpose is to relieve the developer from a significant amount of relational data persistence-related programming tasks.
5.Why do you need ORM tools like hibernate?

The main advantage of ORM like hibernate is that it shields developers from messy SQL. Apart from this, ORM provides following benefits:

  • Improved productivity
    • High-level object-oriented API
    • Less Java code to write
    • No SQL to write
  • Improved performance
    • Sophisticated caching
    • Lazy loading
    • Eager loading
  • Improved maintainability
    • A lot less code to write
  • Improved portability
    • ORM framework generates database-specific SQL for you

6.What Does Hibernate Simplify?

Hibernate simplifies:

  • Saving and retrieving your domain objects
  • Making database column and table name changes
  • Centralizing pre save and post retrieve logic
  • Complex joins for retrieving related items
  • Schema creation from object model

7.What is the need for Hibernate xml mapping file?

Hibernate mapping file tells Hibernate which tables and columns to use to load and store objects. Typical mapping file look as follows:


8.What are the most common methods of Hibernate configuration?

The most common methods of Hibernate configuration are:

  • Programmatic configuration
  • XML configuration (hibernate.cfg.xml)

9.What are the important tags of hibernate.cfg.xml?

Following are the important tags of hibernate.cfg.xml:

10.What are the Core interfaces are of Hibernate framework?

The five core interfaces are used in just about every Hibernate application. Using these interfaces, you can store and retrieve persistent objects and control transactions.

  • Session interface
  • SessionFactory interface
  • Configuration interface
  • Transaction interface
  • Query and Criteria interfaces

11.What role does the Session interface play in Hibernate?

The Session interface is the primary interface used by Hibernate applications. It is a single-threaded, short-lived object representing a conversation between the application and the persistent store. It allows you to create query objects to retrieve persistent objects.

Session session = sessionFactory.openSession();

Session interface role:

  • Wraps a JDBC connection
  • Factory for Transaction
  • Holds a mandatory (first-level) cache of persistent objects, used when navigating the object graph or looking up objects by identifier

12.What role does the SessionFactory interface play in Hibernate?

The application obtains Session instances from a SessionFactory. There is typically a single SessionFactory for the whole application—created during application initialization. The SessionFactory caches generate SQL statements and other mapping metadata that Hibernate uses at runtime. It also holds cached data that has been read in one unit of work and may be reused in a future unit of work

SessionFactory sessionFactory = configuration.buildSessionFactory();

 

13.What is the general flow of Hibernate communication with RDBMS?

The general flow of Hibernate communication with RDBMS is :

  • Load the Hibernate configuration file and create configuration object. It will automatically load all hbm mapping files
  • Create session factory from configuration object
  • Get one session from this session factory
  • Create HQL Query
  • Execute query to get list containing Java objects

14.What is Hibernate Query Language (HQL)?

Hibernate offers a query language that embodies a very powerful and flexible mechanism to query, store, update, and retrieve objects from a database. This language, the Hibernate query Language (HQL), is an object-oriented extension to SQL.
15.How do you map Java Objects with Database tables?

  • First we need to write Java domain objects (beans with setter and getter).
  • Write hbm.xml, where we map java class to table and database columns to Java class variables.

Example :

 

<pre><span style="color: #008000;"><hibernate-mapping></span>
  <span style="color: #008000;"><class</span> <span style="color: #800040;">name</span>=<span style="color: #0000ff;">"com.test.User"</span>  <span style="color: #800040;">table</span>=<span style="color: #0000ff;">"user"</span><span style="color: #008000;">></span>
   <span style="color: #008000;"><property</span>  <span style="color: #800040;">column</span>=<span style="color: #0000ff;">"USER_NAME"</span> <span style="color: #800040;">length</span>=<span style="color: #0000ff;">"255"</span> 
      <span style="color: #800040;">name</span>=<span style="color: #0000ff;">"userName"</span> <span style="color: #800040;">not-null</span>=<span style="color: #800040;">"true"</span>  <span style="color: #800040;">type</span>=<span style="color: #0000ff;">"java.lang.String"</span><span style="color: #008000;">/></span>
   <span style="color: #008000;"><property</span>  <span style="color: #800040;">column</span>=<span style="color: #0000ff;">"USER_PASSWORD"</span> <span style="color: #800040;">length</span>=<span style="color: #0000ff;">"255"</span>
     <span style="color: #800040;">name</span>=<span style="color: #0000ff;">"userPassword"</span> <span style="color: #800040;">not-null</span>=<span style="color: #0000ff;">"true"</span>  <span style="color: #800040;">type</span>=<span style="color: #0000ff;">"java.lang.String"</span><span style="color: #008000;">/></span>
 <span style="color: #008000;"></class></span>
<span style="color: #008000;"></hibernate-mapping></span></pre>
<code>


16.What’s the difference between load() and get()?

load() vs. get() :-

load() get()
Only use the load() method if you are sure that the object exists. If you are not sure that the object exists, then use one of the get() methods.
load() method will throw an exception if the unique id is not found in the database. get() method will return null if the unique id is not found in the database.
load() just returns a proxy by default and database won’t be hit until the proxy is first invoked. get() will hit the database immediately.

17.What is the difference between and merge and update ?

Use update() if you are sure that the session does not contain an already persistent instance with the same identifier, and merge() if you want to merge your modifications at any time without consideration of the state of the session.
18.How do you define sequence generated primary key in hibernate?

Using <generator> tag.
Example:-

 

<pre>
<pre><span style="color: #008000;"><id</span> <span style="color: #800040;">column</span>=<span style="color: #0000ff;">"USER_ID"</span> <span style="color: #800040;">name</span>=<span style="color: #0000ff;">"id"</span> <span style="color: #800040;">type</span>=<span style="color: #0000ff;">"java.lang.Long"</span><span style="color: #008000;">> </span>
<strong> </strong>   <span style="color: #008000;"><generator</span> <span style="color: #800040;">class</span>=<span style="color: #0000ff;">"sequence"</span><span style="color: #008000;">> </span>
     <span style="color: #008000;"><param</span> <span style="color: #800040;">name</span>=<span style="color: #0000ff;">"table"</span>>SEQUENCE_NAME<span style="color: #008000;"></param></span>
<strong> </strong> <span style="color: #008000;"> <generator></span>
<span style="color: #008000;"></id></span></pre>
</pre>
<code>

19.Define cascade and inverse option in one-many mapping?

cascade – enable operations to cascade to child entities.
cascade=”all|none|save-update|delete|all-delete-orphan”

inverse – mark this collection as the “inverse” end of a bidirectional association.
inverse=”true|false”
Essentially “inverse” indicates which end of a relationship should be ignored, so when persisting a parent who has a collection of children, should you ask the parent for its list of children, or ask the children who the parents are?
20.What do you mean by Named – SQL query?

Named SQL queries are defined in the mapping xml document and called wherever required.
Example:

 

<pre><span style="color: #008000;"><sql-query </span><span style="color: #800040;">name</span> =<span style="color: #0000ff;"> "empdetails"</span>>
   <span style="color: #008000;"><return</span> <span style="color: #800040;">alias</span>=<span style="color: #0000ff;">"emp"</span> <span style="color: #800040;">class</span>=<span style="color: #0000ff;">"com.test.Employee"</span><span style="color: #008000;">/></span>
<span style="color: #ff00ff;">      SELECT emp.EMP_ID AS {emp.empid},
                 emp.EMP_ADDRESS AS {emp.address},
                 emp.EMP_NAME AS {emp.name} 
      FROM Employee EMP WHERE emp.NAME LIKE :name</span>
<span style="color: #008000;"></sql-query></span></pre>
<code>


Invoke Named Query :

List people = session.getNamedQuery("empdetails")
		     .setString("TomBrady", name)
		     .setMaxResults(50)
		     .list();

21.How do you invoke Stored Procedures?

<pre><span style="color: #008000;"><sql-query</span> <span style="color: #800040;">name</span>=<span style="color: #0000ff;">"selectAllEmployees_SP"</span> <span style="color: #800040;">callable</span>=<span style="color: #0000ff;">"true"</span><span style="color: #008000;">></span>
<span style="color: #008000;"> <return</span> <span style="color: #800040;">alias</span>=<span style="color: #0000ff;">"emp"</span> <span style="color: #800040;">class</span>=<span style="color: #0000ff;">"employee"</span><span style="color: #008000;">></span>
   <span style="color: #008000;"><return-property</span> <span style="color: #800040;">name</span>=<span style="color: #0000ff;">"empid"</span> <span style="color: #800040;">column</span>=<span style="color: #0000ff;">"EMP_ID"</span><span style="color: #008000;">/></span>       

  <span style="color: #800040;"> <span style="color: #008000;"><return-property</span></span> <span style="color: #800040;">name</span>=<span style="color: #0000ff;">"name"</span> <span style="color: #800040;">column</span>=<span style="color: #0000ff;">"EMP_NAME"</span><span style="color: #008000;">/></span><span style="color: #008000;"> </span>      
  <span style="color: #008000;"> <return-property</span> <span style="color: #800040;">name</span>=<span style="color: #0000ff;">"address"</span> <span style="color: #800040;">column</span>=<span style="color: #0000ff;">"EMP_ADDRESS"</span><span style="color: #008000;">/></span>
    { <span style="color: #000080;">? = call selectAllEmployees()</span> }
<span style="color: #008000;"> </return></span>
<span style="color: #008000;"></sql-query></span></pre>
<code>

22.Explain Criteria API

Criteria is a simplified API for retrieving entities by composing Criterion objects. This is a very convenient approach for functionality like “search” screens where there is a variable number of conditions to be placed upon the result set.
Example :

List employees = session.createCriteria(Employee.class)
		         .add(Restrictions.like("name", "a%") )
		         .add(Restrictions.like("address", "Boston"))
			 .addOrder(Order.asc("name") )
			 .list();

23.Define HibernateTemplate?

org.springframework.orm.hibernate.HibernateTemplate is a helper class which provides different methods for querying/retrieving data from the database. It also converts checked HibernateExceptions into unchecked DataAccessExceptions.

24.What are the benefits does HibernateTemplate provide?

The benefits of HibernateTemplate are :

  • HibernateTemplate, a Spring Template class simplifies interactions with Hibernate Session.
  • Common functions are simplified to single method calls.
  • Sessions are automatically closed.
  • Exceptions are automatically caught and converted to runtime exceptions.

25.How do you switch between relational databases without code changes?

Using Hibernate SQL Dialects , we can switch databases. Hibernate will generate appropriate hql queries based on the dialect defined.
26.If you want to see the Hibernate generated SQL statements on console, what should we do?

In Hibernate configuration file set as follows:
<property name="show_sql">true</property>
27.What are derived properties?

The properties that are not mapped to a column, but calculated at runtime by evaluation of an expression are called derived properties. The expression can be defined using the formula attribute of the element.

28.What is component mapping in Hibernate?

  • A component is an object saved as a value, not as a reference
  • A component can be saved directly without needing to declare interfaces or identifier properties
  • Required to define an empty constructor
  • Shared references not supported

Example:

29.What is the difference between sorted and ordered collection in hibernate? sorted collection vs. order collection :-

sorted collection order collection
A sorted collection is sorting a collection by utilizing the sorting features provided by the Java collections framework. The sorting occurs in the memory of JVM which running Hibernate, after the data being read from database using java comparator. Order collection is sorting a collection by specifying the order-by clause for sorting this collection when retrieval.
If your collection is not large, it will be more efficient way to sort it. If your collection is very large, it will be more efficient way to sort it .
30.What is the advantage of Hibernate over jdbc?  Hibernate Vs. JDBC :-
JDBC Hibernate
With JDBC, developer has to write code to map an object model’s data representation to a relational data model and its corresponding database schema. Hibernate is flexible and powerful ORM solution to map Java classes to database tables. Hibernate itself takes care of this mapping using XML files so developer does not need to write code for this.
With JDBC, the automatic mapping of Java objects with database tables and vice versa conversion is to be taken care of by the developer manually with lines of code. Hibernate provides transparent persistence and developer does not need to write code explicitly to map database tables tuples to application objects during interaction with RDBMS.
JDBC supports only native Structured Query Language (SQL). Developer has to find out the efficient way to access database, i.e. to select effective query from a number of queries to perform same task. Hibernate provides a powerful query language Hibernate Query Language (independent from type of database) that is expressed in a familiar SQL like syntax and includes full support for polymorphic queries. Hibernate also supports native SQL statements. It also selects an effective way to perform a database manipulation task for an application.
Application using JDBC to handle persistent data (database tables) having database specific code in large amount. The code written to map table data to application objects and vice versa is actually to map table fields to object properties. As table changed or database changed then it’s essential to change object structure as well as to change code written to map table-to-object/object-to-table. Hibernate provides this mapping itself. The actual mapping between tables and application objects is done in XML files. If there is change in Database or in any table then the only need to change XML file properties.
With JDBC, it is developer’s responsibility to handle JDBC result set and convert it to Java objects through code to use this persistent data in application. So with JDBC, mapping between Java objects and database tables is done manually. Hibernate reduces lines of code by maintaining object-table mapping itself and returns result to application in form of Java objects. It relieves programmer from manual handling of persistent data, hence reducing the development time and maintenance cost.
With JDBC, caching is maintained by hand-coding. Hibernate, with Transparent Persistence, cache is set to application work space. Relational tuples are moved to this cache as a result of query. It improves performance if client application reads same data many times for same write. Automatic Transparent Persistence allows the developer to concentrate more on business logic rather than this application code.
In JDBC there is no check that always every user has updated data. This check has to be added by the developer. Hibernate enables developer to define version type field to application, due to this defined field Hibernate updates version field of database table every time relational tuple is updated in form of Java class object to that table. So if two users retrieve same tuple and then modify it and one user save this modified tuple to database, version is automatically updated for this tuple by Hibernate. When other user tries to save updated tuple to database then it does not allow saving it because this user does not have updated data.