Step 2 – Configuring Hibernate

Configuring Hibernate is the process of setting up the framework to connect to a database, define mapping files and specify the persistent objects that will be used in the application.

Step 1-

  • Add Hibernate libraries to your project
  • Libraries can be found on the Hibernate website
  • Libraries needed: core Hibernate framework, Hibernate annotations, and database driver

Here is an example of how to add the necessary libraries to a project using Maven:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.22.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-annotations</artifactId>
    <version>3.5.6-Final</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.24</version>
</dependency>

Note – There are several alternative ways to import dependencies without using a pom.xml file:

  1. You can manually download the JAR files for the dependencies and add them to the classpath of your project.
  2. You can use the Gradle or Apache Ivy build tools, which do not require a pom.xml file. Instead, you can specify dependencies in a build.gradle or ivy.xml file.
  3. You can use a package manager such as Maven Wrapper, SDKMAN or Jabba that can download the dependencies and manage them for you, without the need for a pom.xml file.
  4. You can use a build tool like Apache Ant which uses build.xml file instead of pom.xml to manage dependencies.
  5. Some IDEs like Eclipse and IntelliJ IDEA also have support for adding dependencies to a project without using a pom.xml file.

Important-

Hibernate Interfaces/ClassDescription
Configuration classUsed to configure Hibernate settings and create a SessionFactory
Session InterfaceRepresents a single unit of work with the database, used for creating, reading, updating, and deleting objects, and committing or rolling back a transaction
SessionFactory InterfaceFactory for creating Session objects, thread-safe and can be used to create multiple sessions
Transaction InterfaceRepresents a unit of work with the database, used to group multiple operations together and commit or rollback all of them at once
Query InterfaceUsed to execute HQL (Hibernate Query Language) and native SQL queries, can be used to retrieve, update, or delete data
Criteria InterfaceUsed to create type-safe and type-sensitive queries, can be used to retrieve data based on certain criteria, retrieve specific fields, or retrieve data based on certain conditions

Step 2- Next,

  • Create a configuration file named “hibernate.cfg.xml”
  • Include connection details for the database
  • Information to include: database URL, username, password, SQL dialect

Here is an example of a basic hibernate.cfg.xml configuration file:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/mydatabase</property>
        <property name="connection.username">myusername</property>
        <property name="connection.password">mypassword</property>

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

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</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>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">create</property>

        <!-- Mapping files -->
        <mapping resource="com/mypackage/mypersistentobject.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

Note – There are several alternative ways to create a Hibernate configuration file, instead of using a hibernate.cfg.xml file:

1- Using a hibernate.properties file: This file can be used to store Hibernate configuration properties, such as the database connection details and other settings.

# hibernate.properties file
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://localhost:3306/mydatabase
hibernate.connection.username=myusername
hibernate.connection.password=mypassword
hibernate.connection.pool_size=1
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.current_session_context_class=thread
hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
hibernate.mapping.resource=com/mypackage/mypersistentobject.hbm.xml

2- Using a Java class: A Java class can be used to create a Hibernate configuration object, which can be used to configure Hibernate.

import org.hibernate.cfg.Configuration;

public class HibernateConfig {

    public static Configuration getConfig() {
        Configuration config = new Configuration();

        config.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
        config.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/mydatabase");
        config.setProperty("hibernate.connection.username", "myusername");
        config.setProperty("hibernate.connection.password", "mypassword");
        config.setProperty("hibernate.connection.pool_size", "1");
        config.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        config.setProperty("hibernate.current_session_context_class", "thread");
        config.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
        config.setProperty("hibernate.show_sql", "true");
        config.setProperty("hibernate.hbm2ddl.auto", "create");
        config.addResource("com/mypackage/mypersistentobject.hbm.xml");

        return config;
    }
}

3- Using Java-based configuration: A Java-based configuration can be used to configure Hibernate, which eliminates the need for a separate configuration file.

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateConfig {

    public static SessionFactory getSessionFactory() {

        Configuration config = new Configuration();

        // Hibernate settings equivalent to hibernnate.cfg.xml's properties
config.setProperty(Environment.DRIVER, "com.mysql.jdbc.Driver");
config.setProperty(Environment.URL, "jdbc:mysql://localhost:3306/mydatabase");
config.setProperty(Environment.USER, "myusername");
config.setProperty(Environment.PASS, "mypassword");
config.setProperty(Environment.POOL_SIZE, "1");
config.setProperty(Environment.DIALECT, "org.hibernate.dialect.MySQL5InnoDBDialect");
config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
config.setProperty(Environment.CACHE_PROVIDER_CLASS, "org.hibernate.cache.NoCacheProvider");
config.setProperty(Environment.SHOW_SQL, "true");
config.setProperty(Environment.HBM2DDL_AUTO, "create");
config.addResource("com/mypackage/mypersistentobject.hbm.xml");

    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
            .applySettings(config.getProperties()).build();

    return config.buildSessionFactory(serviceRegistry);
}


4- Using Spring: Hibernate can be integrated with Spring, and the configuration can be done using Spring’s configuration file.

<bean id="sessionFactory"
 class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.mypackage" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>

<bean id="dataSource"
 class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydatabase" />
<property name="username" value="myusername" />
<property name="password" value="mypassword" />
</bean>

Step 3- Once the configuration file is set up,

  • After setting up the configuration file, define mapping files
  • These files map persistent objects in the application to database tables
  • Mapping files can be in XML or annotations format
  • They specify the correspondence between fields in persistent objects and columns in database tables.

Here is an example of a basic mapping file, mypersistentobject.hbm.xml, for a class called MyPersistentObject:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.mypackage.MyPersistentObject" table="my_persistent_object">
        <id name="id" column="id" type="long">
            <generator class="increment"/>
        </id>
        <property name="name" column="name" type="string"/>
        <property name="description" column="description" type="string"/>
    </class>
</hibernate-mapping>

Note – Other ways to create same mapping file,

1- Using annotations: Instead of creating a separate mapping file, the mapping information can be added directly to the entity class using annotations, such as @Entity, @Table, @Id, @Column, etc.

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

@Entity
@Table(name = "my_persistent_object")
public class MyPersistentObject {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private long id;

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

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

    // getters and setters
}

2- Using JPA XML Meta-data: JPA also allows you to use an xml file instead of annotations to map the entities.

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
    http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
    version="2.0">
    <entity class="com.mypackage.MyPersistentObject" access="FIELD">
        <table name="my_persistent_object" />
        <attributes>
            <id name="id" >
                <generated-value strategy="IDENTITY" />
            </id>
            <basic name="name" >
                <column name="name" nullable="false" unique="true" />
            </basic>
            <basic name="description" >
                <column name="description"  />
            </basic>
        </attributes>
    </entity>
</entity-mappings>

3- Using programmatic configuration: Instead of using an XML file, you can use a programmatic configuration to map the entities by simply creating an instance of org.hibernate.mapping.PersistentClass and set its properties accordingly.

import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Column;

public class MappingHelper {
    public static void addMapping(Configuration configuration) {
        PersistentClass persistentClass = new PersistentClass(MyPersistentObject.class, configuration.createMappings());
        persistentClass.setTable(configuration.getTable("my_persistent_object"));
        SimpleValue id = new SimpleValue(configuration.createMappings());
        id.setIdentifierGeneratorStrategy("increment");
        id.setTypeName("long");
        id.addColumn(new Column(configuration.getIdentifierColumnName()));
        persistentClass.setIdentifier(id);
        Property name = persistentClass.createProperty("name", new SimpleValue(configuration.createMappings()), "string");
name.setColumn(new Column("name"));
persistentClass.addProperty(name);
Property description = persistentClass.createProperty("description", new SimpleValue(configuration.createMappings()), "string");
description.setColumn(new Column("description"));
persistentClass.addProperty(description);
configuration.addClass(persistentClass);
}
}

Step 4- Finally,

  • Set up Hibernate session factory
  • The session factory is responsible for creating and managing sessions
  • A session is used to interact with the database
  • Through the session factory, you can create, retrieve, and delete persistent objects.

Here is an example of how to set up the Hibernate session factory:

// Create the Configuration
Configuration configuration = new Configuration().configure();

// Create the ServiceRegistry
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.build();

// Create the SessionFactory
SessionFactory sessionFactory = configuration
.buildSessionFactory(serviceRegistry);

Note – Alternative ways to create sessionFactory object –

One alternative way to create the SessionFactory is to use the static method buildSessionFactory() on the Configuration class, like this:

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

Another alternative is to use the SessionFactoryBuilder class, like this:

SessionFactoryBuilder builder = new SessionFactoryBuilder(new StandardServiceRegistryBuilder().configure());
SessionFactory sessionFactory = builder.build();

Note that the configure() method can take the path of the configuration file as an argument and it will load the configuration from that file instead of the default hibernate.cfg.xml file.

SessionFactory sessionFactory = new Configuration().configure("/path/to/config/file").buildSessionFactory();

or

SessionFactoryBuilder builder = new SessionFactoryBuilder(new StandardServiceRegistryBuilder().configure("/path/to/config/file"));
SessionFactory sessionFactory = builder.build();

Step 5 –

  • Once all the steps are completed, use the session factory to create a session
  • Use the session to interact with the database
  • For example, create a new instance of a persistent object and save it to the database using the session.
// Open a new session
Session session = sessionFactory.openSession();

// Begin a transaction
session.beginTransaction();

// Create a new instance of MyPersistentObject
MyPersistentObject myObject = new MyPersistentObject();
myObject.setName("My Object");
myObject.setDescription("This is my persistent object");

// Save the object to the database
session.save(myObject);

// Commit the transaction
session.getTransaction().commit();

// Close the session
session.close();

Note – Alternatively we can use more modern ways to write above codes –

try (Session session = sessionFactory.openSession()) {
    session.beginTransaction();

    MyPersistentObject myObject = new MyPersistentObject();
    myObject.setName("My Object");
    myObject.setDescription("This is my persistent object");

    session.save(myObject);

    session.getTransaction().commit();
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.