Hibernate 5 - Commons DBCP connection pooling example

Posted on May 6, 2017


Technologies used:   Java SE 1.8 | Hibernate 5.2.10.Final | Commons DBCP 2.1.1 | Maven 3.3.9 | MySQL 5.7.12 | Eclipse Neon.3

Hibernate does not provide support for application to use Apache Common DBCP for connection pooling. But we can integrate Common DBCP with Hibernate framework easily.

In this post, I will show you how to configure Common DBCP with Hibernate application.

Jar Dependencies

In pom.xml file of your maven project, add the dependencies below.

pom.xml

  <dependencies>
    <!-- Mysql Connector -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>6.0.5</version>
    </dependency>
    <!-- Hibernate 5.2.9 Final -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.2.10.Final</version>
    </dependency>
    <!-- Apache Common DBCP2  -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-dbcp2</artifactId>
      <version>2.1.1</version>
    </dependency>
  </dependencies>

Hibernate Utility class + Common DBCP configuration

To integrate common dbcp with Hibernate, you need to create a DataSource object.

public static DataSource getDataSource() {
  BasicDataSource dataSource = new BasicDataSource();
  //....
  //....
  return dataSource;
}

Then, set the DataSource in hibernate setting values.

Map<String, Object> settings = new HashMap<>();
//...
settings.put(Environment.DATASOURCE, getDataSource());
//...
registryBuilder.applySettings(settings);

Here is the complete example of HibernateUitl helper class to bootstrap application.

HibernateUtil.java

package com.boraji.tutorial.hibernate;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Environment;

import com.boraji.tutorial.hibernate.entity.Person;
/**
 * @author imssbora
 */
public class HibernateUtil {

   private static StandardServiceRegistry registry;
   private static SessionFactory sessionFactory;

   public static SessionFactory getSessionFactory() {
      if (sessionFactory == null) {
         try {
            StandardServiceRegistryBuilder registryBuilder = 
                  new StandardServiceRegistryBuilder();

            Map<String, Object> settings = new HashMap<>();
            settings.put(Environment.DATASOURCE, getDataSource());
            settings.put(Environment.HBM2DDL_AUTO, "update");
            settings.put(Environment.SHOW_SQL, "true");

            registryBuilder.applySettings(settings);
            registry = registryBuilder.build();
            MetadataSources sources = new MetadataSources(registry)
                  .addAnnotatedClass(Person.class);
            Metadata metadata = sources.getMetadataBuilder().build();
            sessionFactory = metadata.getSessionFactoryBuilder().build();
         } catch (Exception e) {
            if (registry != null) {
               StandardServiceRegistryBuilder.destroy(registry);
            }
            e.printStackTrace();
         }
      }
      return sessionFactory;
   }

   public static void shutdown() {
      if (registry != null) {
         StandardServiceRegistryBuilder.destroy(registry);
      }
   }

   public static DataSource getDataSource() {
      BasicDataSource dataSource = new BasicDataSource();
      dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
      dataSource.setUrl("jdbc:mysql://localhost:3306/BORAJI");
      dataSource.setUsername("root");
      dataSource.setPassword("admin");

      // Connection pooling properties
      dataSource.setInitialSize(0);
      dataSource.setMaxIdle(5);
      dataSource.setMaxTotal(5);
      dataSource.setMinIdle(0);

      return dataSource;
   }
}

Entity class

Create a simple model class with JPA annotations.

Person.java

package com.boraji.tutorial.hibernate.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author imssbora
 */
@Entity
@Table(name = "PERSONS")
public class Person {
  @Id
  @GeneratedValue
  @Column(name = "ID")
  private Long id;

  @Column(name = "NAME")
  private String name;

  // Getter and Setter methods
}

 

Run Application

Create the MainApp class to test the above Common DBCP and Hibernate configuration.

MainApp.java

package com.boraji.tutorial.hibernate;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.boraji.tutorial.hibernate.entity.Person;

/**
 * @author imssbora
 */
public class MainApp {

   public static void main(String[] args) {
      Session session = null;
      Transaction transaction = null;
      try {
         session = HibernateUtil.getSessionFactory().openSession();
         transaction = session.getTransaction();
         transaction.begin();

         Person person=new Person();
         person.setName("Sunil Singh");
         session.save(person);
         
         transaction.commit();
      } catch (Exception e) {
         if (transaction != null) {
            transaction.rollback();
         }
      } finally {
         if (session != null) {
            session.close();
         }
      }
   }
}

Output

Hibernate: create table hibernate_sequence (next_val bigint) engine=MyISAM
Hibernate: insert into hibernate_sequence values ( 1 )
Hibernate: create table PERSONS (ID bigint not null, NAME varchar(255), primary key (ID)) engine=MyISAM
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into PERSONS (NAME, ID) values (?, ?)
Download Sources