Using Hibernate 5 on Payara Server

Photo of Mert Caliskan by Mert Caliskan

Hibernate is the object/relational mapping tool that handles mapping of Java classes to relational tables and Java types to SQL data type. It’s a well-known framework in the Enterprise Java eco-system since it’s being actively developed for the last 16 years.

With this article, I’m going to show the ways of using Hibernate inside a sample application – source code available here – and deploy it onto Payara Server. I will be using the latest version of Hibernate, which is 5.2.10.Final at the time of writing.

 

Getting Started

My sample project is a web application architected with Maven and it contains one simple domain object, its DAO implementation and its REST based web service for exposing CRUD operations to the outside world.

 

Let’s start with the Maven configuration of the project. Hibernate is added as a single dependency to the project since it transitively fetches the necessary dependencies underneath.

 

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>5.2.10.Final</version>
</dependency>

 

For demonstration purposes, the in-memory H2 database will be used for easy configuration. Its dependency definition is as follows:

 

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.192</version>
</dependency>

 

The JDBC resource and Connection Pool definitions are defined in a glassfish-resources.xml file, which is located under the WEB-INF folder. This helps to isolate the definitions within our sample project, and mitigates needing to deal with the Payara Server Admin Console or asadmin commands to define the resources.

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN"
        "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
    <jdbc-resource pool-name="H2Pool"
                   jndi-name="java:app/jdbc/hibernate"/>
    <jdbc-connection-pool name="H2Pool"
                          res-type="javax.sql.DataSource"
                          datasource-classname="org.h2.jdbcx.JdbcDataSource">
        <property name="user" value="sa"/>
        <property name="password" value=""/>
        <property name="url" value="jdbc:h2:mem:hibernateExample"/>
    </jdbc-connection-pool>
</resources>

 

You can see that H2 database URL is defined as in-memory, and the JNDI name mapping that should be used by the project is jdbc/hibernate.

 

The persistence.xml file is used to register a persistence unit to the application at the application level. I am using the registered JDBC Resource that was defined in the glassfish-resources.xml file, and naming the persistence unit as payaraHibernate.

 

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">
    <persistence-unit name="payaraHibernate" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>java:app/jdbc/hibernate</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
        </properties>
    </persistence-unit>
</persistence>

 

By defining the persistence provider, the application will use Hibernate as the underlying ORM. The H2 database is also related to the hibernate.dialect property so that it allows Hibernate to generate H2 optimized SQLs.

 

The Person domain object class is defined as follows:

 

@Entity
@NamedQueries({
        @NamedQuery(name = "Person.findOne", query = "select p from Person p where p.id = :id"),
        @NamedQuery(name = "Person.getAll", query = "select p from Person p")
    }
)
public class Person {

    @Id
    @GeneratedValue
    private long id;
    private String name;
    private String lastName;

    public Person() {
    }

    public Person(String name, String lastName) {
        this.name = name;
        this.lastName = lastName;
    }

    // getter methods
}

 

The DAO implementation for the corresponding Person domain class is as follows:

 

@Stateless
public class PersonDao {

    @PersistenceContext
    private EntityManager entityManager;

    public List<Person> getAll() {
        return entityManager.createNamedQuery("Person.getAll", Person.class).getResultList();
    }

    public Person find(Long id) {
        return entityManager.createNamedQuery("Person.findOne", Person.class).setParameter("id", id).getSingleResult();
    }

    public void save(Person person) {
        entityManager.persist(person);
    }

    public void update(Person person) {
        entityManager.merge(person);
    }

    public void delete(Person person) {
        entityManager.remove(person);
    }
}

 

The REST web service implementation is as follows:

 

@Stateless
@Path("person")
public class PersonResource {

    @Inject
    private PersonDao personDao;

    @GET
    @Produces("application/json")
    public List<Person> all() {
        return personDao.getAll();
    }

    @POST
    @Consumes("application/json")
    public void save(Person person) {
        personDao.save(person);
    }

    @PUT
    @Consumes("application/json")
    public void update(Person person) {
        personDao.update(person);
    }

    @DELETE
    @Path("/{id}")
    @Consumes("application/json")
    public void delete(@PathParam("id") Long id) {
        Person person = personDao.find(id);
        personDao.delete(person);
    }
}

 

After deploying the application onto Payara Server, I can easily invoke the REST web services for creating/updating/deleting person information. To invoke REST, I favored Postman , a GUI tool for API invocation. You can import given Postman project  by yourself (see JSON fileand invoke endpoints deployed on localhost:8080. The URL for the endpoint would be http://localhost:8080/hibernate-example/resources/person for a local deployment.

 

The screenshot below shows the GET request on the provided URL.

 

Hibernate_on_Payara.png

 

 

 

Comments