Wednesday, October 22, 2014

Hibernate Annotations Example

This is an example of how to make use of Hibernate annotations when interacting with a database. Hibernate is is an object-relational mapping library for Java, that provides a framework for mapping an object-oriented domain model to a traditional relational database. It is also an implementation of the Java Persistence API (JPA) specification.
Hibernate provides an easy way to configure how a simple java class will represent an entity class in a database. With the use of JPA annotations you can map a Java class to a table and vice-versa, without having to use xml configuration.
The basic JPA annotations of Hibernate that can be used in an entity are the ones below:
  • @Entity : specifies that the class is an entity.
  • @Table : defines the primary table for the annotated entity.
  • @Column : it is used to specify a mapped column for the persistent field.
  • @Id : defines the primary key field of the entity.
  • @GeneratedValue : allows the auto generation of the field’s values by hibernate, according to strategy attribute.
So, below, we will make use of all the basic hibernate annotations to create, read, update and delete rows from a database table.



Create the entity class

Employee.java class is a class with three properties. It uses all annotations referenced above to be mapped to a table, EMPLOYEE in the database.
Employee.java
01package com.javacodegeeks.snippets.enterprise.hibernate;
02 
03import javax.persistence.Column;
04import javax.persistence.Entity;
05import javax.persistence.GeneratedValue;
06import javax.persistence.GenerationType;
07import javax.persistence.Id;
08import javax.persistence.Table;
09 
10@Entity
11@Table(name = "employee")
12public class Employee {
13 
14    @Id
15    @GeneratedValue(strategy = GenerationType.IDENTITY)
16    @Column(name = "id")
17    private Integer id;
18     
19    @Column(name = "name")
20    private String name;
21     
22    @Column(name="age")
23    private Integer age;
24     
25    public Employee() {
26    }
27 
28    public Employee(Integer id, String name, Integer age) {
29        this.id = id;
30        this.name = name;
31        this.age = age;
32    }
33     
34    public Employee(String name, int age) {
35        this.name = name;
36        this.age = age;
37    }
38    public Integer getId() {
39        return id;
40    }
41 
42    public void setId(Integer id) {
43        this.id = id;
44    }
45 
46    public String getName() {
47        return name;
48    }
49 
50    public void setName(String name) {
51        this.name = name;
52    }
53 
54    public Integer getAge() {
55        return age;
56    }
57 
58    public void setAge(Integer age) {
59        this.age = age;
60    }
61     
62    @Override
63    public String toString() {
64        return "Employee: " + this.id + ", " + this.name + ", " + this.age;
65    }
66     
67}

Configure hibernate

The hibernate.cfg.xml file shown below is where all configuration needed for the interaction with the database is set. So, the database is defined here, as well as the database user credentials. The dialect is set to MySQL, and the driver is the com.mysql.jdbc.Driver. There is also a mapping attribute, where the entity class is defined.
You can also set specific database options here, such as whether the schema will be created or just updated, every time the sessionFactory is created. This is configured in the hibernate.hbm2ddl.auto property, which is set to update. So the schema is only updated. If this property is set to create, then every time we run our application, the schema will be re-created, thus deleting previous data. Another property set here is the show_sql, which specifies whether the sql queries will be shown in the console or the logger.
hibernate.cfg.xml
01<?xml version="1.0" encoding="utf-8"?>
02<!DOCTYPE hibernate-configuration SYSTEM
04 
05<hibernate-configuration>
06   <session-factory>
07   <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
08   <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
09   <property name="hibernate.connection.url">jdbc:mysql://localhost/company</property>
10   <property name="hibernate.connection.username">root</property>
11   <property name="hibernate.connection.password">root</property>
12   <property name="hibernate.hbm2ddl.auto">update</property>
13   <property name="show_sql">false</property>
14   <mapping class="com.javacodegeeks.snippets.enterprise.hibernate.Employee"/>
15</session-factory>
16</hibernate-configuration>

Run the Application

In App.java class we use basic CRUD methods to interact with the database. First of all, the getSessionFactory() is a method that provides a SessionFactory, the creator of Sessions, the basic interfaces between a Java application and Hibernate. The SessionFactory is built with the StandardServiceRegistryBuilder, making use of Configuration. The Configuration is where we can specify properties and mapping documents to be used when creating a SessionFactory.
So, every method that interacts with the database gets a Session, making use of the getSessionFactory(), and the using the openSession() API method of SessionFactory. Then, when needed, a new transaction may open, making use of the beginTransaction() API method of Session. After performing an action, we can commit the transaction and close the session, with getTransaction().commit() and session.close() API methods of Session.
Now, the basic CRUD methods to interact with a database are Create, Read, Update and Delete. Create is done with save(Object object) API method of Session, that persists an entity to the database. Read is done either with load(Class theClass, Serializable id) API method of Session, or by creating a new Query with a String SQL query. Update is easily done by finding and then changing the object. When the object is retrieved from the database within a transaction, any changes to the retrieved object are also performed to the persisted database object. Delete is also performed by making use of an SQL query, or by using delete(Object object) API method of Session.
So, run the example below to see what happens.
First, create a company database and add an employee table, using the SQL statement below:
Create Employee table statement
1CREATE TABLE `company`.`employee` (
2   id INT NOT NULL AUTO_INCREMENT,
3   name VARCHAR(20) default NULL,
4   age INT  default NULL,
5   PRIMARY KEY (id)
6);
Then run the application:
App.java
001package com.javacodegeeks.snippets.enterprise.hibernate;
002 
003import java.util.List;
004 
005import org.hibernate.Query;
006import org.hibernate.Session;
007import org.hibernate.SessionFactory;
008import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
009import org.hibernate.cfg.Configuration;
010 
011public class App {
012     
013    public static void main(String[] args) {
014         
015        Employee em1 = new Employee("Mary Smith", 25);
016        Employee em2 = new Employee("John Aces", 32);
017        Employee em3 = new Employee("Ian Young", 29);
018         
019        System.out.println(" =======CREATE =======");
020        create(em1);
021        create(em2);
022        create(em3);
023        System.out.println(" =======READ =======");
024        List<Employee> ems1 = read();
025        for(Employee e: ems1) {
026            System.out.println(e.toString());
027        }
028        System.out.println(" =======UPDATE =======");
029        em1.setAge(44);
030        em1.setName("Mary Rose");
031        update(em1);
032        System.out.println(" =======READ =======");
033        List<Employee> ems2 = read();
034        for(Employee e: ems2) {
035            System.out.println(e.toString());
036        }
037        System.out.println(" =======DELETE ======= ");
038        delete(em2.getId());
039        System.out.println(" =======READ =======");
040        List<Employee> ems3 = read();
041        for(Employee e: ems3) {
042            System.out.println(e.toString());
043        }
044        System.out.println(" =======DELETE ALL ======= ");
045        deleteAll();
046        System.out.println(" =======READ =======");
047        List<Employee> ems4 = read();
048        for(Employee e: ems4) {
049            System.out.println(e.toString());
050        }
051        System.exit(0);
052    }
053 
054    public static SessionFactory getSessionFactory() {
055        Configuration configuration = new Configuration().configure();
056        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
057                .applySettings(configuration.getProperties());
058        SessionFactory sessionFactory = configuration
059                .buildSessionFactory(builder.build());
060        return sessionFactory;
061    }
062 
063    public static Integer create(Employee e) {
064        Session session = getSessionFactory().openSession();
065        session.beginTransaction();
066        session.save(e);
067        session.getTransaction().commit();
068        session.close();
069        System.out.println("Successfully created " + e.toString());
070        return e.getId();
071 
072    }
073 
074    public static List<Employee> read() {
075        Session session = getSessionFactory().openSession();
076        @SuppressWarnings("unchecked")
077        List<Employee> employees = session.createQuery("FROM Employee").list();
078        session.close();
079        System.out.println("Found " + employees.size() + " Employees");
080        return employees;
081 
082    }
083 
084    public static void update(Employee e) {
085        Session session = getSessionFactory().openSession();
086        session.beginTransaction();
087        Employee em = (Employee) session.load(Employee.class, e.getId());
088        em.setName(e.getName());
089        em.setAge(e.getAge());
090        session.getTransaction().commit();
091        session.close();
092        System.out.println("Successfully updated " + e.toString());
093 
094    }
095 
096    public static void delete(Integer id) {
097        Session session = getSessionFactory().openSession();
098        session.beginTransaction();
099        Employee e = findByID(id);
100        session.delete(e);
101        session.getTransaction().commit();
102        session.close();
103        System.out.println("Successfully deleted " + e.toString());
104 
105    }
106 
107    public static Employee findByID(Integer id) {
108        Session session = getSessionFactory().openSession();
109        Employee e = (Employee) session.load(Employee.class, id);
110        session.close();
111        return e;
112    }
113     
114    public static void deleteAll() {
115        Session session = getSessionFactory().openSession();
116        session.beginTransaction();
117        Query query = session.createQuery("DELETE FROM Employee ");
118        query.executeUpdate();
119        session.getTransaction().commit();
120        session.close();
121        System.out.println("Successfully deleted all employees.");
122 
123    }
124     
125}
When you run the application, you will see that three employees are created, then one is updated, then one is deleted, and finally all employees are deleted. You can debug the example and see what happens in the database after every step. Enjoy!
Output
01=======CREATE =======
02Successfully created Employee: 1, Mary Smith, 25
03Successfully created Employee: 2, John Aces, 32
04Successfully created Employee: 3, Ian Young, 29
05 
06 =======READ =======
07Found 3 Employees
08Employee: 1, Mary Smith, 25
09Employee: 2, John Aces, 32
10Employee: 3, Ian Young, 29
11 
12 =======UPDATE =======
13Successfully updated Employee: 1, Mary Rose, 44
14 
15 =======READ =======
16Found 3 Employees
17Employee: 1, Mary Rose, 44
18Employee: 2, John Aces, 32
19Employee: 3, Ian Young, 29
20 
21 =======DELETE =======
22Successfully deleted Employee: 2, John Aces, 32
23 
24 =======READ =======
25Found 2 Employees
26Employee: 1, Mary Rose, 44
27Employee: 3, Ian Young, 29
28 
29 =======DELETE ALL =======
30Successfully deleted all employees.
31 
32 =======READ =======
33Found 0 Employees