Hibernate Derby tutorial

In this tutorial, we will learn how to use the Hibernate ORM tool with the Derby database. The projects in this tutorial are created in NetBeans IDE.

Hibernate is an object-relational mapping framework for the Java language. It provides a framework for mapping an object-oriented domain model to a relational database. Object-relational mapping (ORM) is a programming technique for converting data between incompatible type systems in object-oriented programming languages.

Apache Derby is an is an open source relational database implemented entirely in Java. Derby has a small footprint and is easy to deploy and install. It supports both embedded and client/server modes.

Hibernate Query Language (HQL) is an object-oriented query language similar to SQL. While SQL operates on tables and columns, HQL operates on persistent objects and their properties. HQL understands inheritance, polymorphism, and association. HQL queries are in the end translated by Hibernate into SQL queries, which do some action on the database.

In addition to its native API, Hibernate contains an implementation of the Java Persistence API (JPA).

Hibernate artifacts

The hibernate.cfg.xml file defines the Hibernate configuration information. It contains information about the database connection, resource mappings, and other connection properties.

SessionFactory is the factory class through which we get sessions and perform database operations. Session is the main runtime interface between a Java application and Hibernate. The main function of the session is to offer create, read, and delete operations for instances of mapped entity classes.

Creating a database in Derby

We create a new testdb database in Derby. It will have a simple Cars table.

Database creation
Figure: Database creation

In the NetBeans' Services tab, we right-click on the Java DB node and select the Create Database option. We give it a testdb name. Note that the database is located in the .netbeans_derby directory of the user's home directory.

cars_derby.sql
CREATE TABLE CARS(ID INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY 
    (START WITH 1, INCREMENT BY 1), NAME VARCHAR(30), PRICE INT);

INSERT INTO CARS(Name, Price) VALUES('Audi', 52642);
INSERT INTO CARS(Name, Price) VALUES('Mercedes', 57127);
INSERT INTO CARS(Name, Price) VALUES('Skoda', 9000);
INSERT INTO CARS(Name, Price) VALUES('Volvo', 29000);
INSERT INTO CARS(Name, Price) VALUES('Bentley', 350000);
INSERT INTO CARS(Name, Price) VALUES('Citroen', 21000);
INSERT INTO CARS(Name, Price) VALUES('Hummer', 41400);
INSERT INTO CARS(Name, Price) VALUES('Volkswagen', 21600);

This is the SQL to create the Cars table; the ID of the car object is auto-incremented. We can use the NetBeans tools to create the Cars table. We right-click on the Databases node and select a New connection option.

Connections
Figure: Connections

A new connection object is created; it is represented by an orange icon. Its context menu provides options to connect to the specified database and execute a command. The Execute command option shows a tool to execute SQL commands. In this window, we can use the above SQL to create the Cars table.

The native Hibernate API and XML mapping

In this section, we create a Java console application that performs some database tasks on a Derby database. We use the Hibernate native API and XML mapping.

Project structure in NetBeans
Project structure in NetBeans

In the above figure, we can see the project structure in NetBeans IDE.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.zetcode</groupId>
    <artifactId>HibernateDerbyEx</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <dependencies>
        
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derbyclient</artifactId>
            <version>10.12.1.1</version>
        </dependency>
    
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.2.Final</version>
        </dependency>

    </dependencies>
    
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>                      
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
    </build>   
</project>

In the pom.xml file, we define two dependencies: the hibernate-core libraries and the derbyclient driver. In the <build> element, we let the build system include XML files — we are going to place XML mapping files into the src/main/java directory.

hibernate.cfg.xml
<?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>
        <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
        <property name="hibernate.connection.username">app</property>
        <property name="hibernate.connection.password">ap</property>
        <property name="hibernate.connection.url">jdbc:derby://localhost:1527/testdb</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <property name="hibernate.dialect"<org.hibernate.dialect.DerbyTenSevenDialect</property>
        <mapping resource="com/zetcode/hibernate/Car.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

In the Hibernate configuration file, we provide the connection properties to the Derby database. We enable Hibernate's automatic session context management and specify a Derby SQL dialect. The mappings are added with the <mapping> element. We have one mapping — of a Car object to the CARS table.

Car.java
package com.zetcode.bean;

public class Car {

    private Long Id;
    private String Name;
    private Integer Price;

    public Long getId() {
        return Id;
    }

    public void setId(Long Id) {
        this.Id = Id;
    }

    public String getName() {
        return Name;
    }

    public void setName(String Name) {
        this.Name = Name;
    }

    public Integer getPrice() {
        return Price;
    }

    public void setPrice(Integer Price) {
        this.Price = Price;
    }
    
    @Override
    public String toString() {
        
        return String.format("Car Id: %d Name: %s; Price: %d", 
                Id, Name, Price);
    }    
}

This is a Car bean. It has three attributes and corresponding getters and setters.

Car.hbm.xml
<?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-mapping>
    <class name="com.zetcode.bean.Car" table="CARS" catalog="app">
        <id name="Id" type="java.lang.Long">
            <column name="Id" />
            <generator class="identity" />
        </id>
        <property name="Name" type="string">
            <column name="Name" length="30"/>
        </property>
        <property name="Price" type="integer">
            <column name="Price" />
        </property>
    </class>
</hibernate-mapping>

In the Car.hbm.xml file, we provide the mapping between the Car class and the CARS table. We map the attributes of the class to the columns of the database table. The mapping is specified between the <hibernate-mapping> and </hibernate-mapping> elements.

<generator class="identity" />

The generator element informs Hibernate what strategy is used to generate primary keys. The identity generator class allows an integer/bigint column to be auto-incremented on demand. This generator is supported by Derby.

HibernateUtils.java
package com.zetcode.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {

    private HibernateUtils() {}

    private static final SessionFactory sessionFactory;

    static {
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    
   public static void shutdown() {
        
        getSessionFactory().close();
    }    
}

The HibernateUtils is a helper class which handles startup and accesses SessionFactory to obtain a session object. The session object is then used to access the database.

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

This line creates a SessionFactory from the hibernate.cfg.xml file.

getSessionFactory().close();

This line closes caches and connection pools.

CarService.java
package com.zetcode.service;

import com.zetcode.bean.Car;
import com.zetcode.util.HibernateUtils;
import java.util.List;
import org.hibernate.Session;

public class CarService {
    
    private CarService() {};
    
    public static Car getCarById(Long id) {
        
        Car car;
        try (Session session = HibernateUtils.getSessionFactory().openSession()) {
            car = session.get(Car.class, id);
        }
        
        return car;
    }    
    
    public static List<Car> getCars() {
        
        List<Car> cars;
        try (Session session = HibernateUtils.getSessionFactory().openSession()) {
            cars = session.createQuery("from Car").list();
        }
        return cars;
    }
    
    public static void save(Car car) {
        
        try (Session session = HibernateUtils.getSessionFactory().openSession()) {
            session.beginTransaction();
            
            session.save(car);
            
            session.getTransaction().commit();
        }
    }
}

In the CarService class we have service methods to obtain a car by its ID, get all cars, and save a new car.

try (Session session = HibernateUtils.getSessionFactory().openSession()) {
    car = session.get(Car.class, id);
}

The HibernateUtils is used to obtain and open a session object. The Session's get() method returns the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance.

cars = session.createQuery("from Car").list();

The createQuery() method creates a new instance of Query for the given HQL query string. The from Car query returns all instances of the Car class.

session.save(car);

The save() method persists the given instance.

HibernateDerbyEx.java
package com.zetcode.main;

import com.zetcode.bean.Car;
import com.zetcode.service.CarService;
import com.zetcode.util.HibernateUtils;
import java.util.List;

public class HibernateDerbyEx {

    public static void main(String[] args) {

        Long id = 1L;

        Car car = CarService.getCarById(id);

        System.out.println(car);

        Car newCar = new Car();

        newCar.setName("Toyota");
        newCar.setPrice(34500);

        CarService.save(newCar);

        List<Car> cars = CarService.getCars();

        for (Car mycar : cars) {

            System.out.println(mycar);
        }

        HibernateUtils.shutdown();
    }
}

This is the main application class. We get a car by its ID, save a new car, and list all cars from the database table.

Long id = 1L;

Car car = CarService.getCarById(id);

We use a CarService's getCarById() method to retrieve a car by its ID.

Car newCar = new Car();

newCar.setName("Toyota");
newCar.setPrice(34500);

CarService.save(newCar);

A new car is created and saved into the database.

List<Car> cars = CarService.getCars();

for (Car mycar : cars) {

    System.out.println(mycar);
}

We list all cars from the CARS table.

HibernateUtils.shutdown();

In the end, we close opened resources.

The native Hibernate API and annotation mapping

In this section, we create a Java console application that performs some database tasks on a Derby database. We use the Hibernate native API and annotation mapping.

The pom.xml, CarService.java, HibernateDerbyNativeEx.java, HibernateUtils.java files do not change. The hibernate.cfg.xml and Car.java do change.

hibernate.cfg.xml
<?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>
        <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
        <property name="hibernate.connection.username">app</property>
        <property name="hibernate.connection.password">ap</property>
        <property name="hibernate.connection.url">jdbc:derby://localhost:1527/testdb</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <property name="hibernate.dialect">org.hibernate.dialect.DerbyTenSevenDialect</property>
        <mapping class="com.zetcode.bean.Car"></mapping>
    </session-factory>
</hibernate-configuration>

In the hibernate.cfg.xml file, the <mapping> element has changed.

<mapping class="com.zetcode.bean.Car"></mapping>

We use a class attribute to point to the Java Entity, which contains the mapping annotations.

Car.java
package com.zetcode.bean;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="CARS")
public class Car implements Serializable {

    private Long Id;
    private String Name;
    private Integer Price;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return Id;
    }

    public void setId(Long Id) {
        this.Id = Id;
    }

    public String getName() {
        return Name;
    }

    public void setName(String Name) {
        this.Name = Name;
    }

    public Integer getPrice() {
        return Price;
    }

    public void setPrice(Integer Price) {
        this.Price = Price;
    }
    
    @Override
    public String toString() {
        
        return String.format("Car Id: %d Name: %s; Price: %d", 
                Id, Name, Price);
    }    
}

In the Car.java class, we define the mappings with the annotations. The names of the class attributes and the names of the table columns are automatically paired. If the names were different, we would have to specify the column names with the @Column annotation.

@Entity
@Table(name="CARS")
public class Car implements Serializable {

The class is decorated with the @Entity annotation; the @Table annotation specifies the primary table for the annotated entity.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {

The @Id annotation specifies the primary key of an entity and the @GeneratedValue provides for the specification of generation strategies for the values of primary keys.

In this tutorial, we have presented the Hibernate ORM. We have used the Derby database. ZetCode has the following related tutorials: EclipseLink tutorial, MySQL Java tutorial, JDBC template tutorial, and Apache Derby tutorial.