Finally http://lovetomakelove.com online dating platform is released! Please join :)

Tuesday, 9 July 2013

Using a Map to represent an entity as name and value pair in JPA

Lets imagine there is a situation when there is a table in the database which contains some attributes as name and value pairs. Having this entity as a collection referencing to the other table using @OneToMany mapping and then looping through it by adding attributes: name as a key and value as a value into the Map is pretty straightforward, but persuading JPA to do the job requires a little bit more work. This tutorial will show exactly how to make this happen using plain JPA. Please note that all the annotation used in the following classes are coming from javax.persistence package. All of them are standard JPA annotations and none of them is framework specific.

Lets start with creating an entity named Attribute:

@Entity
@Table(name = "ATTRIBUTE")
public class Attribute {

    @Id
    private AttributePrimaryKey id;

    @Column(name = "VALUE", nullable = false)
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public AttributePrimaryKey getId() {
        return id;
    }

    public void setId(AttributePrimaryKey id) {
        this.id = id;
    }
}

Now we need to create a class which will represent Attribute's primary key. Lets name this class AttributePrimaryKey:

@Embeddable
public class AttributePrimaryKey implements Serializable {

    @Column(name = "NAME", nullable = false)
    private String name;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "ATTRIBUTE_GROUP_ID")
    private AttributeGroup attributeGroup;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public AttributeGroup getAttributeGroup() {
        return attributeGroup;
    }

    public void setAttributeGroup(AttributeGroup attributeGroup) {
        this.attributeGroup = attributeGroup;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof AttributePrimaryKey)) {
            return false;
        }

        AttributePrimaryKey that = (AttributePrimaryKey) o;

        return !(attributeGroup != null ? !attributeGroup.equals(that.attributeGroup) : that.attributeGroup != null)
                && !(name != null ? !name.equals(that.name) : that.name != null);

    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (attributeGroup != null ? attributeGroup.hashCode() : 0);
        return result;
    }
}

Make sure that equals and hasCode methods are overridden as this is the pirmary key of the Attribute entity and must be unique. And finally we need to create an entity which will hold the actual Map. Lets name it AttributeGroup:

@Entity
@Table(name = "ATTRIBUTE_GROUP")
public class AttributeGroup {

 @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;

    @ElementCollection
    @MapKeyColumn(name = "NAME")
    @Column(name = "VALUE")
    @CollectionTable(name = "ATTRIBUTE", joinColumns = @JoinColumn(name = "ATTRIBUTE_GROUP_ID"))
    private Map<String, String> attributes = new HashMap<>();

    public void createAttribute(String name, String value) {
        AttributePrimaryKey primaryKey = new AttributePrimaryKey();
        primaryKey.setName(name);
        primaryKey.setAttributeGroup(this);

        Attribute attribute = new Attribute();
        attribute.setValue(value);
        attribute.setId(primaryKey);

        attributes.put(name, value);
    }

    public Long getId() {
        return id;
    } 
 
    public Map<String, String> getAttributes() {
        return attributes;
    }
}

So as you see this entity contains a Map<String, String> which represents values from Attribute entity holding a name as a key of the map and value as a value of the Map.

To create these tables in MySQL the following query has to be executed:

    CREATE TABLE ATTRIBUTE (
    NAME VARCHAR(255) NOT NULL,
    VALUE VARCHAR(255) NOT NULL,
    ATTRIBUTE_GROUP_ID BIGINT,
    PRIMARY KEY (ATTRIBUTE_GROUP_ID, NAME));

    CREATE TABLE ATTRIBUTE_GROUP (
    ID BIGINT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (ID));

    ALTER TABLE ATTRIBUTE
    ADD INDEX FK_BBTUDA7EL6XJVERGKSQBRGFTH (ATTRIBUTE_GROUP_ID),
    ADD CONSTRAINT FK_BBTUDA7EL6XJVERGKSQBRGFTH FOREIGN KEY (ATTRIBUTE_GROUP_ID)
    REFERENCES ATTRIBUTE_GROUP (ID);

Sunday, 7 July 2013

Using Hibernate over JPA EntityManager with Spring

Almost every Java developer knows that Hibernate is widely used via it's native approach, but have you ever tried it using via standard JPA (Java Persistence API) approach? Once I have faced an issue in terms of migrating from OpenJPA to Hibernate, but I had to use Hibernate as JPA implementation. The whole internet is full of examples how Hibernate is used via it's native approach, it took me sometime to get it working over JPA also using Spring. This blog contains detailed information how Hibernate can be configured and used via JPA. The benefit of using Hibernate as the implementation of JPA is that if you would want to change the persistence implementation it would be straightforward - you just need to make  sure you are not using any framework specific things. It has to be pure JPA and framework - just an implementation.

Technologies used:
  • Spring 3.2.3.RELEASE
  • Hibernate 4.2.2.Final
  • JPA 2.0
  • MySQL
  • Tomcat 7
  • Maven 3.0.5
  • JDK 1.7
Lets start with reviewing the whole project's structure:

This project contains Spring controller, Spring model attribute, JPA entity, facade to perform JPA EntityManager's operations, Hibernate SQL Schema generator, persistence configuration file, project configuration properties, Spring dispatcher and application context configuration files, deployment descriptor, view page and Maven build file. Before going in details make sure that you have created project structure like shown in this image. We will go through all of these in details in a moment.




























- Creating Maven build script

In the project root folder create a file named pom.xml which will be used to build the whole project into web application archive - .war file, which later in this case will be deployed into Tomcat 7 servlet container.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         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>com.paulius.hibernateviajpa</groupId>
    <artifactId>hibernateviajpa</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <name>${war.symbolicName} [${war.namespace}]</name>

    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF8</project.build.sourceEncoding>
        <maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
        <war.symbolicName>Hibernate Via JPA</war.symbolicName>
        <war.namespace>com.paulius.hibernateviajpa</war.namespace>
        <org.springframework.version>3.2.3.RELEASE</org.springframework.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.2.2.Final</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.2.2.Final</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.0.2.GA</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.1</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.19</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <finalName>HibernateViaJPA##${project.version}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Build-Location>${basedir}</Build-Location>
                            <Build-Machine>${env.COMPUTERNAME}</Build-Machine>
                            <Build-Date>${maven.build.timestamp}</Build-Date>
                        </manifestEntries>
                    </archive>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.1.2</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <phase>deploy</phase>
                        <goals>
                            <goal>jar</goal>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>2.8.1</version>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <phase>install</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <phase>install</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.paulius.hibernateviajpa.util.HibernateDDLGenerator</mainClass>
                    <arguments>
                        <argument>${project.basedir}/target/schema.sql</argument>
                        <argument>com.paulius.hibernateviajpa.entity</argument>
                        <argument>org.hibernate.dialect.MySQLDialect</argument>
                    </arguments>
                </configuration>
            </plugin>

        </plugins>

    </build>

</project>

- Creating Persistence configuration file

Under ../resources/META-INF/ folder create persistence.xml file. The persistence.xml file is a standard configuration file in JPA. It has to be included in the META-INF directory inside of the web application archive that contains the entity beans. The persistence.xml file must define a persistence-unit with a unique name. The provider element specifies the underlying implementation of the JPA EntityManager which in our case is Hibernate. Class element defines full java class name. This class must be persistence entity.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="entityManager" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>com.paulius.hibernateviajpa.entity.Account</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <validation-mode>NONE</validation-mode>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.show_sql" value="false"/>
        </properties>
    </persistence-unit>
</persistence>

- Creating Spring application context file and configuring EntityManager

Under ../webapp/WEB-INF/ folder create a file named applicationContext.xml.
<?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:tx="http://www.springframework.org/schema/tx"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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.2.xsd
       http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
       http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-3.2.xsd
       http://www.springframework.org/schema/tx         http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

    <context:component-scan base-package="com.paulius.hibernateviajpa"/>
    <mvc:annotation-driven/>

    <bean id="jdbcPropertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
          p:location="classpath:project.properties"/>

    <bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource"
          p:driverClassName="${jdbc.driverClassName}"
          p:url="${jdbc.url}"
          p:username="${jdbc.username}"
          p:password="${jdbc.password}"/>

    <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
        <property name="persistenceXmlLocations">
            <list>
                <value>classpath*:META-INF/persistence.xml</value>
            </list>
        </property>
        <property name="defaultDataSource" ref="dataSource"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitManager" ref="persistenceUnitManager"/>
        <property name="persistenceUnitName" value="entityManager"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

- Creating project properties file for JDBC configuration

Under ../resources/ folder create a file named project.properties.
#JDBC configuration
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/hibernate_via_jpa?useEncoding=true&amp;characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root

- Creating Spring dispatcher context file

Under ../webapp/WEB-INF/ folder create a file named dispatcher-servlet.xml.
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="index.htm">indexController</prop>
            </props>
        </property>
    </bean>

    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/views/"
          p:suffix=".jsp"/>

    <bean name="indexController"
          class="org.springframework.web.servlet.mvc.ParameterizableViewController"
          p:viewName="index"/>

</beans>

- Creating web application deployment descriptor

Under ../webapp/WEB-INF/ folder create a file named web.xml.
<?xml version="1.0" encoding="UTF-8"?>
<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_3_0.xsd"
         version="3.0">

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

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

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>redirect.jsp</welcome-file>
    </welcome-file-list>

</web-app>

- Creating redirect.jsp file

Under ../webapp/ folder create a file named redirect.jsp. All views should be stored under the WEB-INF folder so that they are not accessible except through controller process. This JSP is here to provide a redirect to the dispatcher servlet but should be the only JSP outside of WEB-INF.
<%@page contentType="text/html" pageEncoding="UTF-8" %>
<% response.sendRedirect("index.htm"); %>

- Creating the main view file

Under ../webapp/WEB-INF/views/ folder create a file named index.jsp.
<!DOCTYPE html>

<%@page contentType="text/html" pageEncoding="UTF-8" %>

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%--@elvariable id="accounts" type="java.util.List<com.paulius.hibernateviajpa.entity.Account>"--%>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Hibernate Via JPA Example</title>
        <style type="text/css">
            .label {
                display: block;
            }
        </style>
    </head>
    <body>
        <h1>Hibernate Via JPA Example Application</h1>

        <form:form action="${pageContext.servletContext.contextPath}/index.htm" commandName="index">

            <div>
                <form:label cssClass="label" path="name">Name: </form:label>
                <form:input path="name"/>
            </div>

            <div>
                <form:label cssClass="label" path="email">Email address: </form:label>
                <form:input path="email"/>
            </div>

            <div>
                <form:label cssClass="label" path="username">Username: </form:label>
                <form:input path="username"/>
            </div>

            <div>
                <form:label cssClass="label" path="password">Password: </form:label>
                <form:password path="password"/>
            </div>

            <div>
                <input type="submit" value="Register user"/>
            </div>

        </form:form>

        <hr/>

        <div>
            <a href="${pageContext.servletContext.contextPath}/index/show-users.htm">Show all users</a>

            <c:if test="${not empty accounts}">
            <div>
                <h3>Registered Users:</h3>

                <table border="1">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Email</th>
                            <th>Username</th>
                        </tr>
                    </thead>
                    <tbody>
                    <c:forEach var="account" items="${accounts}">
                        <tr>
                            <td><c:out value="${account.name}"/></td>
                            <td><c:out value="${account.email}"/></td>
                            <td><c:out value="${account.username}"/></td>
                        </tr>
                    </c:forEach>
                    </tbody>
                </table>

            </div>
            </c:if>
        </div>

    </body>
</html>

- Creating BaseEntity class. The parent class of all the entities

Create a class: com.paulius.hibernateviajpa.entity.BaseEntity.

This class is the parent class of all the entities in this application. This example contains only one: Account entity. Choosing to use inheritance in JPA it is up to a developer. I prefer this approach so that the primary key of the entity is coming from the parent class and you don't have to define it in each entity.
package com.paulius.hibernateviajpa.entity;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

import java.io.Serializable;

@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;

    public Long getId() {
        return id;
    }
}

- Creating Account class

Create a class: com.paulius.hibernateviajpa.entity.Account.

This class represents a user in the database.
package com.paulius.hibernateviajpa.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

@Entity
@Table(name = "ACCOUNT")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Account extends BaseEntity {

    @Column(name = "NAME", nullable = false)
    private String name;

    @Column(name = "EMAIL", nullable = false)
    private String email;

    @Column(name = "USERNAME", nullable = false)
    private String username;

    @Column(name = "PASSWORD", nullable = false)
    private String password;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    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;
    }

}

- Creating AbstractFacade class to perform JPA operations

Create a class: com.paulius.hibernateviajpa.facade.AbstractFacade.

This class is a generic class and has to be inherited by all other Facade class. In this case only one AccountFacade is extending this class. This approach has been chosen because this class defines only generic methods like: create, find, edit, delete - the standard operations which most likely is going to be used among most of the entities. To have a separate facade for other entities is a benefit so that these methods are used from the parent class and all other - entity specific method is created in the specific facade.
package com.paulius.hibernateviajpa.facade;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaQuery;

import java.util.List;

@SuppressWarnings("unchecked")
public abstract class AbstractFacade<T> {

    @PersistenceContext(unitName = "entityManager")
    private EntityManager entityManager;

    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    public AbstractFacade() {
    }

    protected EntityManager getEntityManager() {
        return this.entityManager;
    }

    public void create(T entity) {
        this.entityManager.persist(entity);
    }

    public void edit(T entity) {
        this.entityManager.merge(entity);
    }

    public void remove(T entity) {
        this.entityManager.remove(this.entityManager.merge(entity));
    }

    public T find(Long primaryKey) {
        return this.entityManager.find(entityClass, primaryKey);
    }

    public List<T> findAll() {
        CriteriaQuery cq = this.entityManager.getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return this.entityManager.createQuery(cq).getResultList();
    }

}

- Creating AccountFacade class to perform JPA operations related to Account entity

Create a class: com.paulius.hibernateviajpa.facade.AccountFacade.

This class is used to perform operation for the specific entity.
package com.paulius.hibernateviajpa.facade;

import com.paulius.hibernateviajpa.entity.Account;

import org.springframework.stereotype.Repository;

@Repository
public class AccountFacade extends AbstractFacade<Account> {

    public AccountFacade() {
        super(Account.class);
    }

}

- Creating user RegistrationForm model attribute class

Create a class: com.paulius.hibernateviajpa.form.RegistrationForm.

This class is used as Spring model attribute which refers to a property of the Model object.
package com.paulius.hibernateviajpa.form;

import java.io.Serializable;

public class RegistrationForm implements Serializable {

    private String name;

    private String email;

    private String username;

    private String password;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    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;
    }
}

- Creating user RegistrationController class

Create a class: com.paulius.hibernateviajpa.controller.RegistrationController.

This class is used to create actual user and store his details in the database. Also it has a facility to retrieve all users later to be displayed in the view.
package com.paulius.hibernateviajpa.controller;

import com.paulius.hibernateviajpa.entity.Account;
import com.paulius.hibernateviajpa.facade.AccountFacade;
import com.paulius.hibernateviajpa.form.RegistrationForm;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;
import java.util.Map;

@Controller
public class RegistrationController {

    @Autowired
    private AccountFacade accountFacade;

    @RequestMapping(value = "index", method = RequestMethod.GET)
    public String showMainView() {
        return "index";
    }

    @ModelAttribute("index")
    public RegistrationForm getRegistrationForm() {
        return new RegistrationForm();
    }

    @Transactional
    @RequestMapping(value = "index", method = RequestMethod.POST)
    public String processRegisterUser(@ModelAttribute("index") RegistrationForm form) {

        Account account = new Account();
        account.setName(form.getName());
        account.setEmail(form.getEmail());
        account.setUsername(form.getUsername());
        account.setPassword(form.getPassword());

        accountFacade.create(account);

        return "index";
    }

    @Transactional
    @RequestMapping(value = "index/show-users", method = RequestMethod.GET)
    public String showAllUsers(Map<String, Object> model) {
        List<Account> accounts = accountFacade.findAll();
        model.put("accounts", accounts);
        return "index";
    }

}

- Creating HibernateDDLGenerator class

Create a class: com.paulius.hibernateviajpa.util.HibernateDDLGenerator.

This class is used to generate MySQL schema - SQL queries to create all tables, indexes, foreign keys. Depending on the provided dialect Hibernate will generate SQL queries for the specific engine. In this case MySQL is used so it will be MySQL queries. Sometimes people are using Hibernate to update database schema automatically once application is being deployed - this is unsafe and definitely should not be used in production, because you don't know what Hibernate is doing in the background and you can't rely on automatic updates, you have to be in control of that yourself. The main method of this class will be called when Maven install command is executed and generated schema will be placed under: ${project.basedir}/target/schema.sql
package com.paulius.hibernateviajpa.util;

import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.tool.hbm2ddl.SchemaExport;

import java.io.File;
import java.io.IOException;

import java.net.URL;

import java.util.Enumeration;
import java.util.LinkedList;

public class HibernateDDLGenerator {

    public static void main(String[] args) {
        execute(args[0], args[1], args[2]);
    }

    private static Iterable<Class> getClasses(String packageName)
            throws ClassNotFoundException, IOException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        String path = packageName.replace('.', '/');
        Enumeration<URL> resources = classLoader.getResources(path);
        LinkedList<File> dirs = new LinkedList<>();
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            dirs.add(new File(resource.getFile()));
        }
        LinkedList<Class> classes = new LinkedList<>();
        for (File directory : dirs) {
            classes.addAll(findClasses(directory, packageName));
        }
        return classes;
    }

    private static LinkedList<Class> findClasses(File directory, String packageName)
            throws ClassNotFoundException {
        LinkedList<Class> classes = new LinkedList<>();
        if (!directory.exists()) {
            return classes;
        }
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    classes.addAll(findClasses(file, packageName + "." + file.getName()));
                } else if (file.getName().endsWith(".class")) {
                    classes.add(Class.forName(
                            packageName + '.'
                                    + file.getName().substring(0, file.getName().length() - 6)));
                }
            }
        }
        return classes;
    }

    private static LinkedList<Class> findAnnotatedClasses(String packageName) {
        LinkedList<Class> classes = new LinkedList<>();
        try {
            for (Class clazz : getClasses(packageName)) {
                classes.add(clazz);
            }
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException("Class not found exception occurred.", ex);
        } catch (IOException ex) {
            throw new RuntimeException("IO exception occurred.", ex);
        }
        return classes;
    }

    private static void execute(String fileName, String packageName, String dialect) {
        Configuration configuration = new Configuration();
        configuration.setProperty(Environment.DIALECT, dialect);
        for (Class<?> entityClass : findAnnotatedClasses(packageName)) {
            configuration.addAnnotatedClass(entityClass);
        }
        SchemaExport schemaExport = new SchemaExport(configuration);
        schemaExport.setDelimiter(";");
        schemaExport.setOutputFile(fileName);
        schemaExport.setFormat(false);
        schemaExport.create(false, false);
    }

}
Once all the above listed files have been created you are ready to build and deploy your application. Don't forget that before deploying it database has to be created. In the project.properties file there is JDBC configuration which most likely will be changed. Before deploying the application you have to create the database named: hibernate_via_jpa and execute the following query which has been generated by HibernateDDLGenerator during Maven install phase:
CREATE TABLE ACCOUNT (
  ID       BIGINT       NOT NULL AUTO_INCREMENT,
  EMAIL    VARCHAR(255) NOT NULL,
  NAME     VARCHAR(255) NOT NULL,
  PASSWORD VARCHAR(255) NOT NULL,
  USERNAME VARCHAR(255) NOT NULL,
  PRIMARY KEY (ID));
Once the query has been executed your database is ready. Start up Tomcat and deploy your application via Tomcat manager. Once application has been deployed open the browser: http://localhost:8080/hibernate-via-jpa/index.htm (I am assuming that your host is localhost and port 8080) and you will see the following window:






















Create a user by entering some details in the form fields. Please note, that there are no validation and you have to specify values for all the fields. Once you have created a user, you can click on the link "Show all users" and all users will be listed in the table just after this link like displayed below: