Hello World application with Hibernate using JPA annotations - Walking Techie

Blog about Java programming, Design Pattern, and Data Structure.

Thursday, May 30, 2019

Hello World application with Hibernate using JPA annotations

Welcome to the Hibernate tutorial from beginner to advance. Hibernate is one of the most popular ORM tool. We will discuss each and every concept in detail. You will find this post very useful even you are beginner or advance in Hibernate.

We will understand the basic concept of Hibernate using the Hello World program with JPA annotations that will be very simple hibernate program, will explain about hibernate concept.

In the previous post, we have discussed about the Hello World program using the mapping file.

Hello World Program with JPA annotations

We will create the hello-world-hibernate-jpa-anno gradle based application. Project structure of this application is something like below.

Hello World with Hibernate using JPA annotations Project Structure

Hibernate Properties

hibernate.cfg.xml is a Hibernate configuration xml file which contain the required Hibernate properties. Most of the properties have their own default value. Some of the properties values need to have into this file, so Hibernate use these properties to create connection with database.

<?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>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/helloworld?useSSL=false</property>
        <property name="connection.username">root</property>
        <property name="connection.password">santosh</property>
        <property name="hbm2ddl.auto">update</property>

        <!-- SQL Dialect -->
        <property name="dialect">org.hibernate.dialect.MariaDBDialect</property>
        <!--Echo all executed SQL query to console-->
        <property name="show_sql">true</property>
        <mapping class="com.walking.techie.entity.Message"/>

    </session-factory>
</hibernate-configuration>

This table show some of the important properties that you will use into Hibernate configuration file.

Properties Description
connection.driver_class The JDBC driver class.
connection.url The JDBC URL to the database instance.
connection.username The database username to authenticate.
connection.password The database password to authenticate.
hbm2ddl.auto This property validates or exports schema DDL to the database when the SessionFactory is created.
dialect This property makes Hibernate to generate the appropriate SQL for the chosen database.
show_sql This property echo the generated SQL query on console.

Create SessionFactory

Usually an application has single SessionFactory instance and Session instance can get from this factory instance. Client request served by threads using Session instance.

The internal state of a SessionFactory is immutable. Once it is created this internal state is set. This internal state includes all of the metadata about Object/Relational Mapping.

package com.walking.techie.utils;


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;

public class HibernateUtil {

    public static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
                    .configure("hibernate.cfg.xml").build();
            Metadata metadata = new MetadataSources(standardRegistry).getMetadataBuilder().build();
            return metadata.getSessionFactoryBuilder().build();
        } catch (Exception ex) {
            System.err.println("Initial session factory creation failed: " + ex.getMessage());
            throw new ExceptionInInitializerError();
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

Model

Message Java class is a persistence entity that will save into relational database. I have used the lombok annotation here to create getter, setter, default constructor of the Message class.

package com.walking.techie.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@Entity
@Table(name = "MESSAGE")
public class Message {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "ID")
  private Long id;

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

  public Message(String message) {
    this.message = message;
  }
}

In the previous post, we have used XML based mapping file to specify mapping between Message class and "MESSAGE" table. In XML based metadata that will have to manage in separate file for each and every entity class.
@Entity: specifies that the class is an entity. This annotation is applied to the entity class.
@Table: specifies the name of the table in database with which entity class is mapped.
@Id: This annotation specifies the primary key of the entity.
@GeneratedValue: This annotation specifies the generation strategies for the values of primary keys.
@Column: is used to specify the mapped column for a persistent property or field.
Now let's see, how Hibernate using these annotations for Message entity class in details:

The @Entity annotation tells Hibernate that Message class is a persistent entity that to have its state persisted to the "helloworld" database.
The @Table annotation specifies the name of the table and we are mapping it to the "MESSAGE" table.
The @Id annotation indicate that id attribute or field of this class represents a primary key or unique identifier of message table and @GeneratedValue annotation with auto strategy tells hibernate that whenever a new message entity is persisted to the "helloworld" database. The database generate the unique primary key value for that entity and the hibernate is going to set the value of this id attribute using the newly generated primary key value. This is same as what native strategy in the mapping file was doing for us.
The @Column annotation tells Hibernate about the column you want to map this id attribute and message attribute to "ID" and "MESSAGE" respectively in the "MESSAGE" table.

Then one final change we need to make in hibernate.cfg.xml file is to change the mapping resource attribute to a mappingclass attribute and specify the class we declared as entity.

HelloWorldClient

This class main method will save the message object into MESSAGE table of helloworld database.

package com.walking.techie;

import com.walking.techie.entity.Message;
import com.walking.techie.utils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

public class HelloWorldClient {
  public static void main(String[] args) {
    // get session factory of an application
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

    // Open a session
    Session session = sessionFactory.openSession();

    // Begin a unit of work and return the associated Transaction object.
    Transaction transaction = session.beginTransaction();

    Message message = new Message("Hello world with hibernate using JPA annotations");

    // save the message object into table
    session.save(message);

    // commit the transaction
    transaction.commit();

    // End the session by releasing the JDBC connection and cleaning up.
    session.close();
  }
}

Before running this application you need to create the helloworld database into MySQL. Table will created automatically because we have set the hbm2ddl.auto to update.

Output

This application will save the message object in MESSAGE table.

output in console

May 30, 2019 3:55:59 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.2.12.Final}
May 30, 2019 3:55:59 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
May 30, 2019 3:55:59 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
May 30, 2019 3:55:59 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
May 30, 2019 3:55:59 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/helloworld?useSSL=false]
May 30, 2019 3:55:59 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {user=root, password=****}
May 30, 2019 3:55:59 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
May 30, 2019 3:55:59 PM org.hibernate.engine.jdbc.connections.internal.PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
May 30, 2019 3:55:59 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MariaDBDialect
May 30, 2019 3:56:00 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@71454b9d] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: create table hibernate_sequence (next_val bigint) engine=InnoDB
Hibernate: insert into hibernate_sequence values ( 1 )
Hibernate: create table MESSAGE (ID bigint not null, MESSAGE varchar(255), primary key (ID)) engine=InnoDB
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 MESSAGE (MESSAGE, ID) values (?, ?)

find the above working code from git.

No comments :

Post a Comment