My Works

Hibernate based Embedded Database Server Example.

Here we are going to look at creating a Embedded Server and Hibernate Client using Hibernate HSQLServer.Hibernate based Embedded Database Server is useful in cases where it provides as own database for small and medium sized projects.

  1. Create Parent Project with Modules.
  2. Create Module EmbeddedServer with Module Dependencies.
  3. Create Server Admin Class.
  4. Create Servlets to Start and Stop embedded server along with relevant JSP pages.
  5. Create Integration tests for Server Admin and Servlets.
  6. Create Module Hibernate Client with Module Dependencies.
  7. Create a Account and Developer Class with a Relationship.
  8. Create Integration tests for Hibernate Client.
  9. Run the Junit Tests and Check the data.
  10. Download The Example.

1.Create Parent Project with Modules.

Create a project folder EmbeddedDBServerHibernate containing a parent POM. Add EmbeddedDB and HibernateClient as modules in the Parent POM. Please Refer this link for some more information on Multi Module Project.



<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>EmbeddedDB</groupId>
<artifactId>EmbeddedDBServerHibernate</artifactId>
<version>1.0</version>
<packaging>pom</packaging>

<modules>
<module>EmbeddedServer</module>
<module>HibernateClient</module>
</modules>
</project>


2.Create Module EmbeddedServer with Module Dependencies.

Create a module EmbeddedServer with Project dependencies described as JDK 1.6 or above, Hibernate jar , hsqldb jar, other Spring dependency jar, logging jars, junit jar, are the ones we would need. The pom file dependencies are listed below.



<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<parent>
<groupId>EmbeddedDB</groupId>
<artifactId>EmbeddedDBServerHibernate</artifactId>
<version>1.0</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<groupId>EmbeddedDB</groupId>
<artifactId>EmbeddedServer</artifactId>
<version>1.0</version>
<packaging>war</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.2.3.RELEASE</spring.version>
</properties>

<repositories>

<!-- spring bundle repository -->

<repository>
<id>com.springsource.repository.bundles.release</id>
<name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</name>
<url>http://repository.springsource.com/maven/bundles/release</url>
</repository>

<repository>
<id>com.springsource.repository.bundles.external</id>
<name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
<url>http://repository.springsource.com/maven/bundles/external</url>
</repository>

<!-- jboss Repository -->

<repository>
<id>JBoss</id>
<name>JBoss Repsitory</name>
<layout>default</layout>
<url>http://repository.jboss.org/maven2</url>
</repository>

</repositories>

<dependencies>

<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.5.ga</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
</exclusions>
</dependency>

<!-- JSR 303 with Hibernate Validator -->

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>com.springsource.javax.servlet</artifactId>
<version>2.5.0</version>
<scope>provided</scope>
</dependency>

<!-- log libarary slf4j-bridge for commons-logging -->

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.0</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.0</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.0</version>
</dependency>

<!-- Test Dependencies -->

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web.servlet</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>

</dependencies>

<build>

<extensions>

<extension>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</extension>

</extensions>

<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>

<!-- Plugin de Jetty para deploy -->

<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<webApp> ${project.build.directory}/${project.build.finalName}</webApp>
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
</plugin>

<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<directory>src\main\webapp</directory>
</resource>
</webResources>
</configuration>
</plugin>

</plugins>

<finalName>EmbeddedServer</finalName>

</build>

<reporting>

<plugins>

<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jxr-maven-plugin</artifactId>
<version>2.3</version>
</plugin>

<plugin>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.16</version>
</plugin>

</plugins>

</reporting>

</project>



3.Create Server Admin Class.

Create a class ServerAdmin in EmbeddedServer project, this class would start and shut HSQLServer.The class has methods to make simple connection to the Server whereby it helps in creating an User or Altering Rights and also helps in checking as to whether the database connection is active.

Please Refer this link for some more information on HSQLDB Guide.


public class ServerAdmin {
private Server hsqlServer;
private static final Logger logger = LoggerFactory.getLogger(ServerAdmin.class);

public void setUpEmbeddedServer() {
setHsqlServer(new Server());
getHsqlServer().setLogWriter(null);
getHsqlServer().setSilent(true);
getHsqlServer().setDatabaseName(0, "embeddeddb");
getHsqlServer().setDatabasePath(0, "file:data/embeddeddb;ifexists=false;shutdown=false");
}

public void startEmbeddedServer() {
logger.info("Starting Embedded Server");
if (getHsqlServer().getState() == SERVER_STATE_SHUTDOWN) {
getHsqlServer().start();
}
Connection conn = callConnection(null, "SA", "");
logger.info("Altering to add new User and user rights");
alterCreateUser(conn);
alterUserRights(conn);
}

public void shutEmbeddedServer(Connection conn) {
logger.info("Shutting down...");
Statement statement;
try {
statement = conn.createStatement();
statement.executeUpdate("SHUTDOWN COMPACT");
statement.close();
logger.info("Shut Down Completed");
} catch (SQLException e) {
logger.info(e.getMessage());
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
logger.info(e.getMessage());
e.printStackTrace();
}
}
}

public Connection shutEmbeddedServer(Server server, Connection conn) {
logger.info("Shutting down...");
Statement statement;
try {
statement = conn.createStatement();
statement.executeUpdate("SHUTDOWN COMPACT");
statement.close();
conn.close();
conn = null;
logger.info("Shut Down Completed");
} catch (SQLException e) {
try {
conn.close();
} catch (SQLException e1) {
logger.info(e1.getMessage());
e1.printStackTrace();
}
conn = null;
logger.info(e.getMessage());
e.printStackTrace();
} finally {
server.stop();
server.shutdown();
}
return conn;
}

public Server getHsqlServer() {
return hsqlServer;
}

public void setHsqlServer(Server hsqlServer) {
this.hsqlServer = hsqlServer;
}

public static Connection callConnection(Connection conn, String dbuser, String dbpassword) {
String dburl = "jdbc:hsqldb:hsql://localhost/data/embeddeddb;hsqldb.write_delay=false;shutdown=false;close_result=true;";
logger.info("Establishing connection" + dburl);
try {
loadDriver();
conn = DriverManager.getConnection(dburl, dbuser, dbpassword);
logger.info("connection established and connection closed is " + conn.isClosed());
} catch (SQLException e1) {
logger.info(e1.getMessage());
e1.printStackTrace();
}
return conn;
}

public static Connection callConnection(Connection conn) {
conn = callConnection(conn, "techbrightworks", "password");
return conn;
}

public static Connection simpleConnection() {
String dburl = "jdbc:hsqldb:hsql://localhost/data/embeddeddb;";
logger.info("Connecting: " + dburl);
Connection conn = null;
try {
loadDriver();
conn = DriverManager.getConnection(dburl, "techbrightworks", "password");
} catch (SQLException e1) {
logger.info("Error:" + e1.getMessage());
}
return conn;
}
public static boolean isDatabaseConnectionActive() {
boolean databaseConnectionActive = false;
Connection conn = simpleConnection();
if (null != conn) {
databaseConnectionActive = true;
try {
conn.close();
} catch (SQLException e) {
logger.info("Error:" + e.getMessage());
e.printStackTrace();
}
} else {
databaseConnectionActive = false;
}
return databaseConnectionActive;
}

private void alterCreateUser(Connection conn) {
Statement statement;
try {
statement = conn.createStatement();
statement.executeUpdate("CREATE USER 'techbrightworks' PASSWORD 'password'");
statement.close();
conn = null;
logger.info("Alter done to create a new user");
} catch (SQLException e) {
conn = null;
logger.info(e.getMessage());
}
}

private void alterUserRights(Connection conn) {
Statement statement;
try {
statement = conn.createStatement();
statement.executeUpdate("GRANT DBA TO TECHBRIGHTWORKS");
statement.close();
conn = null;
logger.info("Alter rights for new user");
} catch (SQLException e) {
conn = null;
logger.info(e.getMessage());
}
}

private static void loadDriver() {
try {
Class.forName("org.hsqldb.jdbcDriver");
} catch (ClassNotFoundException e) {
logger.info(e.getMessage());
e.printStackTrace();
}
}
}


4.Create Servlets to Start and Stop embedded server along with relevant JSP pages.

We need to invoke the ServerAdmin class to start and shut the server, therefore we would provide for two servlets one to start the server and another to stop the server. Moreover web.xml Referring to the servlets has to be provided in the webapp/WEB-INF.

Now there is a provision to invoke the servlet via respective JSP action whereby start and shutdown of Embedded Server can be invoked by loading the respective page.

The hibernate.cfg and log4j.properties are to be provided in the resources.

4.a The Servlet Admin_Servlet_Start.


public class Admin_Servlet_Start extends HttpServlet {

private static final long serialVersionUID = -1550041299484535649L;
private static ServerAdmin server;
private static final Logger logger = LoggerFactory.getLogger(Admin_Servlet_Start.class);
public Admin_Servlet_Start() {
super();
}
public static ServerAdmin getServer() {
return server;
}

public static void setServer(ServerAdmin server) {
Admin_Servlet_Start.server = server;
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Connection conn = null;
if (!ServerAdmin.isDatabaseConnectionActive()) {
Admin_Servlet_Start.setServer(new ServerAdmin());
Admin_Servlet_Start.getServer().setUpEmbeddedServer();
Admin_Servlet_Start.getServer().startEmbeddedServer();
conn = ServerAdmin.callConnection(conn);
response.getWriter().print("Server_Started");
} else {
logger.info("server already started");
response.getWriter().print("server already started");
}
}

public void doGet(HttpServletRequest request, HttpServletResponse response) {
// No Get Requests
}
}

4.b The Servlet Admin_Servlet_ShutDown.


public class Admin_Servlet_ShutDown extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(Admin_Servlet_ShutDown.class);
private static final long serialVersionUID = 1L;
public Admin_Servlet_ShutDown() {
super();
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (ServerAdmin.isDatabaseConnectionActive()) {
Connection conn = ServerAdmin.simpleConnection();
if (conn != null) {
conn = Admin_Servlet_Start.getServer().shutEmbeddedServer(Admin_Servlet_Start.getServer().getHsqlServer(), conn);
response.getWriter().print("ShutDown_Completed");
} else {
logger.info("The DatabaseActive but Connection is null");
response.getWriter().print("The DatabaseActive but Connection is null");
}
} else {
logger.info("The server is already closed");
response.getWriter().print("The server is already closed");
}
}

public void doGet(HttpServletRequest request, HttpServletResponse response) {
// No Get Requests
}
}


4.c The web.xml Referring the Servlets.


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5"
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">
<display-name>EmbeddedServer</display-name>
<servlet>
<display-name>Admin_Servlet_Start</display-name>
<servlet-name>Admin_Servlet_Start</servlet-name>
<servlet-class>org.srinivas.siteworks.hibernate.Admin_Servlet_Start</servlet-class>
</servlet>
<servlet>
<display-name>Admin_Servlet_ShutDown</display-name>
<servlet-name>Admin_Servlet_ShutDown</servlet-name>
<servlet-class>org.srinivas.siteworks.hibernate.Admin_Servlet_ShutDown</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Admin_Servlet_Start</servlet-name>
<url-pattern>/Admin_Servlet_Start</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Admin_Servlet_ShutDown</servlet-name>
<url-pattern>/Admin_Servlet_ShutDown</url-pattern>
</servlet-mapping>
</web-app>


4.d EmbeddedServer Start JSP Page.



<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>EmbeddedServer Start Page</title>
</head>
<body onload="document.frm.submit();">
<form name="frm" method="post" action="Admin_Servlet_Start">
<fieldSet>
<table>
<tr>
<td>Start Database Server:</td>
<td colspan="2"><div id="infostartdatabase"	style="color: blue;"></div></td>
</tr>
</table>
</fieldSet>
</form>
</body>
</html>


4.e EmbeddedServer ShutDown JSP Page.



<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>EmbeddedServer ShutDown Page</title>
</head>
<body onload="document.form.submit();">
<form name="form" method="post" action="Admin_Servlet_ShutDown">
<fieldSet>
<table>
<tr>
<td>Shutdown Database Server:</td>
<td colspan="2"><div id="infoshutdowndatabase" style="color: blue;"></div></td>
</tr>
</table>
</fieldSet>
</form>
</body>
</html>


4.f Provide for hibernate.cfg in the resources.



<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

<session-factory>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>

<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url"></property>
<property name="connection.username"></property>
<property name="connection.password"></property>
<property name="connection.shutdown">false</property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.connection.autocommit">true</property>

<!-- JDBC connection pool (use the built-in one) -->
<property name="connection.pool_size">1</property>

<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache  -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

</session-factory>

</hibernate-configuration>


4.g Provide for log4j.properties in the resources.



#Root logger option
log4j.rootLogger=INFO,standard
 
#Direct log messages to standard
log4j.appender.standard=org.apache.log4j.ConsoleAppender
log4j.appender.standard.Target=System.out
log4j.appender.standard.layout=org.apache.log4j.PatternLayout
log4j.appender.standard.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c: %m%n


5.Create Integration tests for Server Admin and Servlets.

The tests cover starting and shutting of the Embedded Server invoked via ServerAdmin class and also invoked via Servlet.

To verify using a Servlet invoked starting and shut down of EmbeddedServer, Spring based spring-servlet.xml is created in the src/test/resources source folder and Test Controller is created in a org.srinivas.siteworks package of src/test/java source folder. The controller invoke the servlet which thereby invoke ServerAdmin for start and ShutDown of Embedded Server.

5.a The spring-servlet.xml in Test resources.



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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">
<bean name="/StartPage.jsp"
class="org.srinivas.siteworks.TestController" />
<bean name="/ShutPage.jsp"
class="org.srinivas.siteworks.TestController" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>src/main/webapp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>


5.b The TestController class.


package org.srinivas.siteworks;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.srinivas.siteworks.hibernate.Admin_Servlet_Start;
import org.srinivas.siteworks.hibernate.Admin_Servlet_ShutDown;
public class TestController extends AbstractController {

@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {

if(request.getRequestURI().equals("/StartPage.jsp")){
Admin_Servlet_Start startServlet = new Admin_Servlet_Start();
startServlet.doPost(request, response);

}else if(request.getRequestURI().equals("/ShutPage.jsp")){
Admin_Servlet_ShutDown shutServlet =  new Admin_Servlet_ShutDown();
shutServlet.doPost(request, response);
}
return new ModelAndView();
}
}


5.c The ServerAdminTest class covering tests based ServerAdmin methods.


public class ServerAdminTest {
private Connection conn;
private ServerAdmin server;

@Before
public void setUp() {
conn = null;
server = new ServerAdmin();
server.setUpEmbeddedServer();
}

public void shutDatabase() {
server.shutEmbeddedServer(server.getHsqlServer(), conn);
}

@Test
public void testStartDatabase() {
server.startEmbeddedServer();
conn = ServerAdmin.callConnection(conn);
assertNotNull(conn);
shutDatabase();
}

@Test
public void testShutDatabase() throws SQLException {
server.startEmbeddedServer();
Connection conn = ServerAdmin.callConnection(null);
conn = server.shutEmbeddedServer(server.getHsqlServer(), conn);
assertEquals(server.getHsqlServer().getState(), SERVER_STATE_SHUTDOWN);
assertNull(conn);
}
}


5.d The EmbeddedServerTest class covering tests invoked via Servlet and it is based on Spring.

Please Refer this link for some more information on Spring Based Mock and MockHttpServletRequest.


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/test/resources/spring-servlet.xml")
public class EmbeddedServerTest {

@Test
public void testStartEmbeddedServerPage() throws ServletException, IOException {
MockHttpServletRequest request = new MockHttpServletRequest(new MockServletContext(""), "POST", "/StartPage.jsp");
MockHttpServletResponse response = new MockHttpServletResponse();
DispatcherServlet dispatcherServlet = new DispatcherServlet() ;
dispatcherServlet.setContextConfigLocation("file:src/test/resources/spring-servlet.xml");
dispatcherServlet.init(new MockServletConfig());
dispatcherServlet.service(request, response);
String resp = response.getContentAsString();
assertEquals("Server_Started", resp.trim());
shutServer();
}

@Test
public void testShutDownEmbeddedServerPage() throws ServletException, IOException {
useServerAdminStart();
MockHttpServletRequest request = new MockHttpServletRequest(new MockServletContext(""), "POST", "/ShutPage.jsp");
MockHttpServletResponse response = new MockHttpServletResponse();
DispatcherServlet dispatcherServlet = new DispatcherServlet() ;
dispatcherServlet.setContextConfigLocation("file:src/test/resources/spring-servlet.xml");
dispatcherServlet.init(new MockServletConfig());
dispatcherServlet.service(request, response);
String resp = response.getContentAsString();
assertEquals("ShutDown_Completed", resp.trim());
}

private void useServerAdminStart() {
ServerAdmin server = new ServerAdmin();
server.setUpEmbeddedServer();
server.startEmbeddedServer();
Connection conn = null;
conn =  ServerAdmin.callConnection(conn);
assertNotNull(conn);
Admin_Servlet_Start.setServer(server);
}

private void shutServer() {
Admin_Servlet_Start.getServer().shutEmbeddedServer(Admin_Servlet_Start.getServer().getHsqlServer(), ServerAdmin.callConnection(null));
}

}


5.e When EmbeddedServer.war is manually deployed to tomcat and the JSP pages related Start and ShutDown of EmbeddedServer are loaded.

EmbeddedServer Start Page

EmbeddedServer Start Page

EmbeddedServer Shut Page

EmbeddedServer Shut Page

6.Create Module Hibernate Client with Module Dependencies.

Create a module Hibernate Client with Project dependencies described as JDK 1.6 or above, Hibernate jar , hsqldb jar, hibernate-annotations jar, other logging jars, junit jar and httpclient jars are the ones we would need.Maven plugin to support integration tests using webserver is also added. The pom file dependencies are listed below.



<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<parent>
<groupId>EmbeddedDB</groupId>
<artifactId>EmbeddedDBServerHibernate</artifactId>
<version>1.0</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<groupId>EmbeddedDB</groupId>
<artifactId>HibernateClient</artifactId>
<version>1.0</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.2.3.RELEASE</spring.version>
</properties>

<repositories>

<!-- spring bundle repository -->

<repository>
<id>com.springsource.repository.bundles.release</id>
<name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</name>
<url>http://repository.springsource.com/maven/bundles/release</url>
</repository>

<repository>
<id>com.springsource.repository.bundles.external</id>
<name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
<url>http://repository.springsource.com/maven/bundles/external</url>
</repository>

<!-- jboss Repository -->

<repository>
<id>JBoss</id>
<name>JBoss Repository</name>
<layout>default</layout>
<url>http://repository.jboss.org/maven2</url>
</repository>

</repositories>

<dependencies>

<!-- Junit and Hibernate -->

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.0.GA</version>
</dependency>

<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>


<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.3.0.ga</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.3.0.ga</version>
</dependency>

<!-- log libarary slf4j-bridge for commons-logging -->

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.0</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.0</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.0</version>
</dependency>

<!-- http client dependencies -->

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.1.1</version>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.1.1</version>
</dependency>

</dependencies>

<build>

<plugins>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>EmbeddedDB</groupId>
<artifactId>EmbeddedServer</artifactId>
<version>1.0</version>
<type>war</type>
<overWrite>true</overWrite>
<outputDirectory>target/webapps</outputDirectory>
<destFileName>EmbeddedServer.war</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
<webApp>${basedir}/target/webapps</webApp>
<contextHandlers>
<contextHandler implementation="org.mortbay.jetty.webapp.WebAppContext">
<war>${basedir}/target/webapps/EmbeddedServer.war</war>
<contextPath>/EmbeddedServer</contextPath>
</contextHandler>
</contextHandlers>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<excludes>
<exclude>**/*$*</exclude>
<exclude>**/*HibernateClientTest.java</exclude>
</excludes>
</configuration>
</plugin>



<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.6</version>
<configuration>
<encoding>UTF-8</encoding>
<includes>
<include>**/HibernateClientTest.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>


</plugins>
<finalName>HibernateClient</finalName>
</build>

<reporting>

<plugins>

<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jxr-maven-plugin</artifactId>
<version>2.3</version>
</plugin>

<plugin>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.16</version>
</plugin>

</plugins>

</reporting>

</project>



7.Create a Account and Developer Class with a Relationship.

An Account has a Developer is the Relation.The hibernate.cfg and log4j.properties are to be provided in the resources.The web.xml is left as Default.

Please Refer this link for some more information on Hibernate Documentation, Hibernate ORM Documentation and Java Persistence.

7.a The Entity Account Class.


@Entity
@Table(name = "Registered_Accounts")
public class Account {

@Id
@Column(name = "Account_Id")
@GenericGenerator(name = "kaugen", strategy = "increment")
@GeneratedValue(generator = "kaugen")
private Integer accountId;
@Column(name = "User_Name")
private String userName;

@Column(name = "User_Password")
private String password;

@Column(name = "Created_Date")
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;

@OneToOne
@JoinColumn(name="Developer_Id")
private Developer developer;

public Integer getAccountId() {
return accountId;
}
public void setAccountId(Integer accountId) {
this.accountId = accountId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public Developer getDeveloper() {
return developer;
}
public void setDeveloper(Developer developer) {
this.developer = developer;
}

}

7.b The Entity Developer Class.


@Entity
@Table(name = "Developer_Details")
public class Developer {

@Id
@Column(name = "DeveloperId")
@GenericGenerator(name = "actgen", strategy = "increment")
@GeneratedValue(generator = "actgen")
private Integer developerId;

@Column(name = "First_Name")
private String firstName;

@Column(name = "Last_Name")
private String lastName;

@Column(name = "Email_Address")
private String emailAddress;

@Column(name = "SkillSet")
private String skillSet;

public Integer getDeveloperId() {
return developerId;
}
public void setDeveloperId(Integer developerId) {
this.developerId = developerId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getSkillSet() {
return skillSet;
}
public void setSkillSet(String skillSet) {
this.skillSet = skillSet;
}
}


7.c Provide for hibernate.cfg in the resources.



<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>

<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:hsql://localhost/data/embeddeddb;shutdown=false;close_result=true</property>
<property name="connection.username">techbrightworks</property>
<property name="connection.password">password</property>
<property name="connection.shutdown">false</property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.connection.autocommit">true</property>

<!-- JDBC connection pool (use the built-in one) -->
<property name="connection.pool_size">5</property>

<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache  -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

<!-- List all the annotated classes we're using -->
<mapping class="org.srinivas.siteworks.hibernate.Account"/>
<mapping class="org.srinivas.siteworks.hibernate.Developer"/>

</session-factory>

</hibernate-configuration>


7.d Provide for log4j.properties in the resources.


#Root logger option
log4j.rootLogger=INFO,standard 
#Direct log messages to standard
log4j.appender.standard=org.apache.log4j.ConsoleAppender
log4j.appender.standard.Target=System.out
log4j.appender.standard.layout=org.apache.log4j.PatternLayout
log4j.appender.standard.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c: %m%n

8.Create Integration tests for Hibernate Client.

Now Hibernate Client database calls to perform save and delete action on table rows is verified by creating and using Integration Tests comprising both the modules the HibernateClient and the EmbeddedServer. To verify the tests at command prompt level maven-jetty-plugin is used in the POM.xml.This maven-jetty-plugin is configured to start the EmbeddedServer module context on the jetty server. ThereAfter Http Client calls are made to start the EmbeddedServer database. Now The HibernateClient is ready to make call to perform save, update and delete actions.

Please Refer this link for some more information on Maven Jetty Plugin Documentation.

8.a HibernateClientTestUtility class provides the methods used by the Test class.


public class HibernateClientTestUtility {

private static final Logger logger = LoggerFactory.getLogger(HibernateClientTestUtility.class);

public static void saveAccount() {
Session session = null;
Transaction tx = null;
Configuration configuration = new AnnotationConfiguration().configure();
configuration.setProperty("hibernate.connection.url", "jdbc:hsqldb:hsql://localhost/data/embeddeddb;shutdown=false;close_result=true");
SessionFactory sf = configuration.buildSessionFactory();
session = sf.openSession();
tx = session.beginTransaction();
Account account = new Account();
account.setUserName("click123");
account.setPassword("password");
account.setCreatedDate(new Date());
Account accountTwo = new Account();
accountTwo.setUserName("srinivas");
accountTwo.setPassword("password");
accountTwo.setCreatedDate(new Date());
Developer developer = new Developer();
developer.setFirstName("Click");
developer.setLastName("Lock");
developer.setEmailAddress("click.lock@lock.com");
developer.setSkillSet("Shell");
account.setDeveloper(developer);
Developer developerTwo = new Developer();
developerTwo.setFirstName("Srinivas");
developerTwo.setLastName("Jasti");
developerTwo.setEmailAddress("srinivas.jasti@techbrightworks.com");
developerTwo.setSkillSet("Java");
accountTwo.setDeveloper(developerTwo);
try {
session.save(developerTwo);
session.save(accountTwo);
session.save(developer);
session.save(account);
tx.commit();
session.flush();
session.close();
sf.close();
} catch (HibernateException e) {
e.printStackTrace();
if (tx != null && tx.isActive())
tx.rollback();
}
}

@SuppressWarnings("unchecked")
public static void deleteAccount() {
Session session = null;
Transaction tx = null;
SessionFactory sf = new AnnotationConfiguration().configure().buildSessionFactory();
session = sf.openSession();
tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Account.class);
criteria.add(Restrictions.eq("userName", "click123"));
List<Account> users = (ArrayList<Account>) criteria.list();
for (Account user : users) {
logger.info("Deleting User:");
session.delete(user.getDeveloper());
session.delete(user);
}
tx.commit();
session.close();
sf.close();
}

@SuppressWarnings("unchecked")
public static List<Developer> queryDevelopers() {
Session session;
Query query;
SessionFactory sf3 = new AnnotationConfiguration().configure().buildSessionFactory();
session = sf3.openSession();
session.beginTransaction();
query = (Query) session.createQuery("from Developer");
List<Developer> developers = (ArrayList<Developer>) query.list();
for (Developer developer : developers) {
logger.info("developerId is:  " + developer.getDeveloperId());
logger.info("firstname is:  " + developer.getFirstName());
logger.info("lastname is:  " + developer.getLastName());
logger.info("email is:  " + developer.getEmailAddress());
logger.info("skillset is:  " + developer.getSkillSet());
}
session.getTransaction().commit();
logger.info("developers size is:" + developers.size());
session.close();
sf3.close();
return developers;
}

@SuppressWarnings("unchecked")
public static List<Account> queryAccounts() {
Session session;
SessionFactory sf2 = new AnnotationConfiguration().configure().buildSessionFactory();
session = sf2.openSession();
session.beginTransaction();
Query query = (Query) session.createQuery("from Account");
List<Account> accounts = (ArrayList<Account>) query.list();
for (Account account : accounts) {
logger.info("usernameis: " + account.getUserName());
logger.info("password is:  " + account.getPassword());
logger.info("accountid is:  " + account.getAccountId());
logger.info("createdDate is:  " + account.getCreatedDate());
}
session.getTransaction().commit();
logger.info("accounts size is:" + accounts.size());
session.close();
sf2.close();
return accounts;
}

public static Account findYourAccount(String emailAddress, List<Account> accounts) {
Account resultAccount = null;
for (Account account : accounts) {
if (account.getDeveloper().getEmailAddress().equals(emailAddress)) {
resultAccount = account;
}
}
return resultAccount;
}

public static Developer findYourDeveloper(String emailAddress, List<Developer> developers) {
Developer resultDeveloper = null;
for (Developer developer : developers) {
if (developer.getEmailAddress().equals(emailAddress)) {
resultDeveloper = developer;
}
}
return resultDeveloper;
}
}


8.b HibernateClientTest class which verifies the basic save and delete actions.

Please Refer this link for some more information on Http Client Documentation and Http Client Core Documentation.


public class HibernateClientTest {
private static final Logger logger = LoggerFactory.getLogger(HibernateClientTest.class);
private DefaultHttpClient httpclient;

@Before
public void startServer() {
httpclientCall("http://localhost:8080/EmbeddedServer/Admin_Servlet_Start");
}

@After
public void shutClient() {
httpclientCall("http://localhost:8080/EmbeddedServer/Admin_Servlet_ShutDown");
httpclient.getConnectionManager().shutdown();
}

@Test
public void testSaveAccount() {
HibernateClientTestUtility.saveAccount();
List<Developer> developers = HibernateClientTestUtility.queryDevelopers();
Developer resultDeveloper = HibernateClientTestUtility.findYourDeveloper("srinivas.jasti@techbrightworks.com", developers);
assertTrue(resultDeveloper.getSkillSet().equals("Java"));
assertEquals("Srinivas", resultDeveloper.getFirstName());
List<Account> accounts = HibernateClientTestUtility.queryAccounts();
Account resultAccount = HibernateClientTestUtility.findYourAccount("srinivas.jasti@techbrightworks.com", accounts);
assertEquals("srinivas", resultAccount.getUserName());
Developer resultDeveloperTwo = HibernateClientTestUtility.findYourDeveloper("click.lock@lock.com", developers);
assertTrue(resultDeveloperTwo.getSkillSet().equals("Shell"));
assertEquals("Click", resultDeveloperTwo.getFirstName());
Account resultAccountTwo = HibernateClientTestUtility.findYourAccount("click.lock@lock.com", accounts);
assertEquals("click123", resultAccountTwo.getUserName());
}

@Test
public void testDeleteAccount() {
HibernateClientTestUtility.deleteAccount();
List<Developer> developers = HibernateClientTestUtility.queryDevelopers();
Developer resultDeveloper = HibernateClientTestUtility.findYourDeveloper("srinivas.jasti@techbrightworks.com", developers);
assertTrue(resultDeveloper.getSkillSet().equals("Java"));
assertEquals("Srinivas", resultDeveloper.getFirstName());
List<Account> accounts = HibernateClientTestUtility.queryAccounts();
Account resultAccount = HibernateClientTestUtility.findYourAccount("srinivas.jasti@techbrightworks.com", accounts);
assertEquals("srinivas", resultAccount.getUserName());
Developer resultDeveloperTwo = HibernateClientTestUtility.findYourDeveloper("click.lock@lock.com", developers);
assertNull(resultDeveloperTwo);
}

private void httpclientCall(String url) {
httpclient = new DefaultHttpClient();
HttpResponse response;
try {
HttpPost httpPost = new HttpPost(url);
response = httpclient.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
logger.info("Response Status:" + response.getStatusLine());
if (responseEntity != null) {
logger.info("Response content length: " + responseEntity.getContentLength());
logger.info(response.toString());
}
logger.info("Response Code : " + response.getStatusLine().getStatusCode());
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

9.Run the Junit Tests and Check the data.

Now the setup is ready to execute unit tests and integration tests of both the modules EmbeddedServer and HibernateClient while building the parent project EmbeddedDBServerHibernate from the commandline.Go to the path of parent project EmbeddedDBServerHibernate and use the command mvn clean install eclipse:clean eclipse:eclipse -Dwtpversion=2.0.This would build both Parent Project, Modules within the parent Projects.The EmbeddedServer.war is created in the target of EmbeddedServer Module which is then used as context to execute the integration test of the Module Hibernate Client. To execute the Hibernate Client Integration Test from eclipse, have m2e plugin installed on your eclipse and create a m2 Maven Build configuration with Goal verify integration-test and execute the Integration Test.

Now the parent Project is Build along with Executions of Tests successfully.Further go to the path of the parent project EmbeddedDBServerHibernate a folder data is available with two files embeddeddb.properties and embeddeddb.script.The embeddeddb.script represent log of the outcome sqlcommands for the Integration test executed from HibernateClient module.Also EmbeddedServer module would also have a folder of data with two files embeddeddb.properties and embeddeddb.script for the tests executed from EmbeddedServer module.

Building Projects with Multiple Modules

Building Projects with Multiple Modules

EmbeddedServer Test Results

EmbeddedServer Test Results

Starting Jetty Before Hibernate Client Integration Test

Starting Jetty Before Hibernate Client Integration Test

Hibernate Client Integration Test Result

Hibernate Client Integration Test Result

Build Summary

Build Summary

Hibernate Client M2E Configuration

Hibernate Client M2E Configuration

9a.An Example of embeddeddb.script representing a log of the outcome sqlcommands for the Integration test executed from HibernateClient module.


CREATE SCHEMA PUBLIC AUTHORIZATION DBA
CREATE MEMORY TABLE DEVELOPER_DETAILS(DEVELOPERID INTEGER NOT NULL PRIMARY KEY,EMAIL_ADDRESS VARCHAR(255),FIRST_NAME VARCHAR(255),LAST_NAME VARCHAR(255),SKILLSET VARCHAR(255))
CREATE MEMORY TABLE REGISTERED_ACCOUNTS(ACCOUNT_ID INTEGER NOT NULL PRIMARY KEY,CREATED_DATE TIMESTAMP,USER_PASSWORD VARCHAR(255),USER_NAME VARCHAR(255),DEVELOPER_ID INTEGER,CONSTRAINT FK58F32D0343B5BA6A FOREIGN KEY(DEVELOPER_ID) REFERENCES DEVELOPER_DETAILS(DEVELOPERID))
CREATE USER SA PASSWORD ""
CREATE USER TECHBRIGHTWORKS PASSWORD "PASSWORD"
GRANT DBA TO SA
GRANT DBA TO TECHBRIGHTWORKS
SET WRITE_DELAY 10
SET SCHEMA PUBLIC
INSERT INTO DEVELOPER_DETAILS VALUES(1,'srinivas.jasti@techbrightworks.com','Srinivas','Jasti','Java')
INSERT INTO REGISTERED_ACCOUNTS VALUES(1,'2014-08-30 04:38:42.380000000','password','srinivas',1)

10.Download The Example.