Hibernate Persistence Example

0

In this article, I will show you how to store an order entity using hibernate as the persistence engine. We will be using MySQL as the database and Maven as the build tool.

Below are my setup details:

  1. Maven 3.2.3
  2. Hibernate 5.0.0.CR1 RELEASE
  3. Eclipse  as the IDE, version Luna 4.4.1.

Dependencies

Add the following dependencies:

  1. hibernate-core the core hibernate library
  2. mysql-connector-java for database driver
  3. slf4j-log4j12 for logging
  4. javassist hibernate uses this for Java bytecode manipulation

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javarticles.spring.hibernate</groupId>
	<artifactId>hibernateExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.26</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.12</version>
		</dependency>
		<dependency>
			<groupId>javassist</groupId>
			<artifactId>javassist</artifactId>
			<version>3.12.1.GA</version>
		</dependency>

	</dependencies>

	<properties>
		<hibernate.version>5.0.0.CR1</hibernate.version>
	</properties>

</project>

Logging

Hibernate uses commons logging. You can either use Log4j and JDK 1.4 logging. In this example, we will use Log4j. You need to create a log4j.properties in src/main/resources dir. See Log4j Example for more details.

Entity Class

The example we chose is about orders so let’s first create the entity class that represents the order.

Order:

package com.javarticles.hibernate;

import java.util.Date;

public class Order {
    private Long orderId;
    private String orderNbr;
    private Date orderDate;
    private String orderDesc;
    private Long orderQty;
    
    public Order(){}
    
    public Order(String orderNbr) {
        this.orderNbr = orderNbr;
    }
    
    public Long getOrderId() {
        return orderId;
    }
    private void setOrderId(Long orderId) {
        this.orderId = orderId;
    }
    public Date getOrderDate() {
        return orderDate;
    }
    public void setOrderDate(Date orderDate) {
        this.orderDate = orderDate;
    }
    public String getOrderDesc() {
        return orderDesc;
    }
    public void setOrderDesc(String orderDesc) {
        this.orderDesc = orderDesc;
    }
    public Long getOrderQty() {
        return orderQty;
    }
    public void setOrderQty(Long orderQty) {
        this.orderQty = orderQty;
    }
    public String toString() {
        return "Order: nbr[" + orderNbr + "] date [" + orderDate + "] desc[" + orderDesc + "] qty[" + orderQty + "]";
    }
}

Each java bean property represents a column in the database table. It is not a mandatory to have a getter and setter method for each property. If note, orderNbr is not having getter and setter. Even though orderNbr is a private member, Hibernate can still access it but it is recommended that the properties are represented in java bean style.
The other important member to note here is the orderId which is the unique identifier value for the order row. We want the orderId to be generated internally by the database so we the setter for orderId is private.
The no-argument constructor is mandatory for all persistent classes as Hibernate uses Java Reflection to create the object.

Object Relational Mapping for the class

The java bean defined above needs to be mapped to a database table so that hibernate can figure how to load and store the entity. All persistence classes need a mapping.
The top most element is <hibernate-mapping> and each first-class entity is mapped within <class>. We will know more about this is in a separate article just on the mapping.

orders.hbm.xml:

<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.javarticles.hibernate">
	<class name="com.javarticles.hibernate.Order" table="orders">
		<id name="orderId" column="order_id">
			<generator class="native" />
		</id>
		<property name="orderNbr" column="order_nbr" type="string" length="30" access="field"/>
		<property name="orderDesc" column="order_desc" type="string"
			length="60" />
		<property name="orderDate" type="timestamp" column="order_date"/>
		<property name="orderQty" column="qty" type="long" />
	</class>
</hibernate-mapping>

Note the access attribute of orderNbr property is set to field as we don’t have a setter and getter. If we don’t specify the attribute, it will use the java bean accessor methods to set and get the object.
Other thing to notice is the nested generator element of the <id> element, it represents the identifier generation strategy. We have set it to native so that it relies on database generated sequences. The mapping XML is self-explanatory. If you don’t specify the column attribute then it will use the property name as column name.
If you don’t specify type it will try to derive it from the java bean using reflection but it is highly recommended to explicitly specify the column names and types.

Hibernate Configuration

Hibernate needs to know the database settings, connection pooling and the mapping files to load. We specify these properties in hibernate configuration file.

hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.password">admin</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost/test</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hbm2ddl.auto">update</property>		
		<property name="current_session_context_class">thread</property>
		<mapping resource="orders.hbm.xml" />
	</session-factory>
</hibernate-configuration>

Few things to note here. We are using Hibernate built-in connection pool. The hbm2ddl.auto is set to update so that the schema is automatically created in the database. We have specified the mapping file in property resource. Property current_session_context_class is set to thread as we want the Session object created to be stashed in the thread context.

Create, retrieve and delete using hibernate

In the below example, we first create SessionFactory.

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

org.hibernate.SessionFactory is a thread-safe global object that is used to create Session objects. A org.hibernate.Session represents a single unit of work. The below statement returns the Session object bound to the current Java thread that executes the application.

Session session = sessionFactory.getCurrentSession();

org.hibernate.Transaction represents the underlying transaction.

Transaction tx = session.getTransaction();

We call transaction.begin() to start the transaction and transaction.commit() or transaction.rollback to end the transaction.
Once we have started the transaction, we delete the existing orders for the sample order nbr. Next, we create a new order and then we retrieve the order created. Wwe call session.save(order) to save the order.

HibernateExample:

package com.javarticles.hibernate;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import org.hibernate.MappingException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class HibernateExample {

    public static void main(String[] args) throws MappingException, IOException {
        Configuration configuration = new Configuration().configure();
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.getTransaction();
        tx.begin();
        Query query = session.createQuery("from Order where orderNbr='ORD01'");
        List list = query.list();
        System.out.println("Orders found: " + list.size());
        for(Order order: list) {
            session.delete(order);
            System.out.println("Deleted " + order);
        }
        tx.commit();
        
        session = sessionFactory.getCurrentSession();
        tx = session.getTransaction();
        tx.begin();
        Order order = new Order("ORD01");         
        order.setOrderDesc("Laptop");
        order.setOrderQty(2L);
        order.setOrderDate(new Date());
        session.save(order);
        tx.commit();
        
        session = sessionFactory.getCurrentSession();
        tx = session.getTransaction();
        tx.begin();
        query = session.createQuery("from Order where orderNbr='ORD01'");
        System.out.println("List all orders: " + query.list());
        tx.commit();
        
        sessionFactory.close();
    }
}

Output:

23:29| INFO | Version.java 37 | HHH000412: Hibernate Core {5.0.0.CR1}
23:29| INFO | Environment.java 222 | HHH000206: hibernate.properties not found
23:29| INFO | Environment.java 329 | HHH000021: Bytecode provider name : javassist
23:29| INFO | JavaReflectionManager.java 66 | HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
23:29| WARN | LocalXmlResourceResolver.java 70 | HHH000223: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/hibernate-mapping. Use namespace http://www.hibernate.org/dtd/hibernate-mapping instead. Refer to Hibernate 3.6 Migration Guide!
23:29| WARN | DriverManagerConnectionProviderImpl.java 76 | HHH000402: Using Hibernate built-in connection pool (not for production use!)
23:29| INFO | DriverManagerConnectionProviderImpl.java 149 | HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost/test]
23:29| INFO | DriverManagerConnectionProviderImpl.java 158 | HHH000046: Connection properties: {user=root, password=****}
23:29| INFO | DriverManagerConnectionProviderImpl.java 163 | HHH000006: Autocommit mode: false
23:29| INFO | DriverManagerConnectionProviderImpl.java 85 | HHH000115: Hibernate connection pool size: 20 (min=1)
23:29| INFO | Dialect.java 154 | HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
23:29| INFO | SchemaUpdate.java 101 | HHH000228: Running hbm2ddl schema update
23:29| INFO | QueryTranslatorFactoryInitiator.java 47 | HHH000397: Using ASTQueryTranslatorFactory
Orders found: 1
Deleted Order: nbr[ORD01] date [2015-06-06 23:06:02.0] desc[Laptop] qty[2]
List all orders: [Order: nbr[ORD01] date [2015-06-06 23:29:33.0] desc[Laptop] qty[2]]
23:29| INFO | DriverManagerConnectionProviderImpl.java 264 | HHH000030: Cleaning up connection pool [jdbc:mysql://localhost/test]

Download the source code

This was an example about hibernate persistence.

You can download the source code here: hibernatePersistenceExample.zip
Share.

Comments are closed.