Hibernate Criteria Query

Hibernate Criteria Query API lets you create nested, structured query expressions in Java, it gives you an object oriented control over the queries, it provides a compile time syntax check which is not possible with a query language like HQL or SQL.

Since Hibernate 5.2, the Hibernate Criteria API is deprecated and 
new development is focused on the JPA Criteria API.

Hibernate version that We are using here :

<dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-core</artifactId>
     <version>5.4.11.Final</version>
</dependency>

Hibernate Criteria Query : Example

Employee Entity

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

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

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

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

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

// getters & setters & toString()
// ...
}

Fetch Employees from the Database using Criteria Query

// Criteria Query Example
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Employee> cr = cb.createQuery(Employee.class);
Root<Employee> root = cr.from(Employee.class);
cr.select(root);

Query criteriaQuery = session.createQuery(cr);
List<Employee> results = query.getResultList();
results.forEach(System.out::println); // print all Employee records

Explanation Step by Step :

  1. Create an instance of Session from the SessionFactory object
  2. Create an instance of CriteriaBuilder by calling the getCriteriaBuilder() method
  3. Create an instance of CriteriaQuery by calling the CriteriaBuilder createQuery() method
  4. Create an instance of Query by calling the Session createQuery() method
  5. Call the getResultList() method of the query object which gives us the results
  6. At last using java 8 for each loop to print the records.

Summary

In this tutorial, we focused on the basics of Criteria Queries in Hibernate and JPA,
Hope you liked it !


Hibernate Cascading Levels

In Simple terms, Cascading in Hibernate means the propagation of same action(for eg: save, delete, etc.) from Parent to Child level entity.

Depending on what type of action to perform there are different cascade types.

Let’s have a look at an example:

Employee.java Entity Class

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

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

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

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

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name="EMPLOYEE_ID")
    private Set<Project> projects;
	...
}

Project.java Entity Class

@Entity
public class Project {
   @Id
   private Integer projectId;
   private String projectDescription;
   private String projectDuration;
  
   @OneToOne (mappedBy="projects",  fetch = FetchType.LAZY)
   private Employee employee;
   ...
}

cascade=CascadeType.ALL” essentially means that any change which happens on Employee Entity must cascade to Project Entity as well. If you save an employee, then all associated projects will also be saved into database. If you delete an Employee then all projects associated with that Employee will also be deleted.

But what if we only want to cascade only save operations but not delete operation. Then we need to clearly specify it using correct CascadeType, see the below code.

@OneToMany(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name="EMPLOYEE_ID")
private Set<Project> projects;

Now only when save() or persist() methods are called using employee instance then only projects will be persisted. If any other method is called on session, it’s effect will not affect/cascade to projects.

JPA – Cascade Types

The cascade types supported by the Java Persistence Architecture are as below:

  1. CascadeType.PERSIST : cascade type presist means that save() or persist() operations cascade to related entities.
  2. CascadeType.MERGE : cascade type merge means that related entities are merged when the owning entity is merged.
  3. CascadeType.REFRESH : cascade type refresh does the same thing for the refresh() operation.
  4. CascadeType.REMOVE : cascade type remove removes all related entities association with this setting when the owning entity is deleted.
  5. CascadeType.DETACH : cascade type detach detaches all related entities if a “manual detach” occurs.
  6. CascadeType.ALL : cascade type all is shorthand for all of the above cascade operations.

There is no default cascade type in JPA. By default no operations are cascaded.

Hibernate – Cascade Types

Now lets understand what is cascade in hibernate in which scenario we use it.

Apart from JPA provided cascade types, there is one more cascading operation in hibernate which is not part of the normal set above discussed, called “orphan removal“. This removes an owned object from the database when it’s removed from its owning relationship.

Let’s understand with an example. In our Employee and Project entity example, I have updated them as below and have mentioned “orphanRemoval = true” on projects. It essentially means that whenever I will remove a ‘ project from projects set’ (which means I am removing the relationship between that project and Employee); the project entity which is not associated with any other Employee on database (i.e. orphan) should also be deleted.

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

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

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

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

    @OneToMany(orphanRemoval = true, mappedBy = "employee")
    private Set<Project> projects;
	...
}

Summary

In this tutorial, we have seen different ways to use cascade type operations in JPA hibernate.
I hope you liked it !


Spring 5 + Hibernate 5 integration Only annotations without xml configuration

Learn How to Create a Spring 5 + Hibernate 5 application using Only annotations without xml configuration in really easy way.

Let’s Begin Coding

1. Final Project Structure – will look like this

spring-hibernate-with-annotations-project-structure

2. Add jar dependencies to pom.xml

In this project we will use Spring 5, Hibernate 5 and mySql DB stack.

To use the above technology stack add the following dependencies in your pom.xml file as below.

<?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>SpringHibernate</groupId>
    <artifactId>com.pt</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <!-- https://mvnrepository.com/artifact/
             org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/
             org.springframework/spring-orm -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/
             mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/
             org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.11.Final</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/
             org.apache.commons/commons-dbcp2 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.7.0</version>
        </dependency>

        </dependency>
    </dependencies>

    <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
    </build>

</project>

2. Create Entity Class

Employee.java Entity Class

package com.pt.entities;

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

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

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

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

    public Employee() {}

    public Employee(int id, String firstName, 
                    String lastName, String address) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.address = address;
    }

    public int getId() {
        return id;
    }

    public void setId( int id ) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName( String first_name ) {
        this.firstName = first_name;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName( String last_name ) {
        this.lastName = last_name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

3. Create DAO Layer

Create Data Access Object layer:
1. Dao Interface
2. Dao Implementation Class

EmployeeDao.java Interface

package com.pt.dao;

import com.pt.entities.Employee;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeDao {

        void add(Employee employee);

}

EmployeeDaoImpl.java Class

package com.pt.dao;

import com.pt.entities.Employee;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class EmployeeDaoImpl implements EmployeeDao {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public void add(Employee employee) {
        sessionFactory.getCurrentSession().save(employee);
    }
}

4. Create Service Layer

Create Service layer:
1. Service Interface
2. Service Implementation Class

EmployeeService.java Interface

package com.pt.services;

import com.pt.entities.Employee;


public interface EmployeeService {

    void add(Employee employee);

}

EmployeeServiceImpl.java Class

package com.pt.services;

import com.pt.dao.EmployeeDao;
import com.pt.entities.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    public EmployeeDao employeeDao;

    @Transactional
    @Override
    public void add(Employee employee) {
        employeeDao.add(employee);
    }
}

5. Create db.properties File

db.properties

# MySQL properties
db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/testdb
db.username=root
db.password=root

# Hibernate properties
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

6. Create Configs Class File

AppConfig.Java Class

package com.pt.configs;

import com.pt.entities.Employee;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@PropertySource("classpath:db.properties")
@EnableTransactionManagement
@ComponentScans(value = {
        @ComponentScan("com.pt.dao"),
        @ComponentScan("com.pt.services")
})

public class AppConfig {

        @Autowired
        private Environment env;

        @Bean
        public DataSource getDataSource() {
            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName(env.getProperty("db.driver"));
            dataSource.setUrl(env.getProperty("db.url"));
            dataSource.setUsername(env.getProperty("db.username"));
            dataSource.setPassword(env.getProperty("db.password"));
            return dataSource;
        }

        @Bean
        public LocalSessionFactoryBean getSessionFactory() {
            LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
            factoryBean.setDataSource(getDataSource());

            Properties props=new Properties();
            props.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
            props.put("hibernate.dialect",env.getProperty("hibernate.dialect"));
            props.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
            factoryBean.setHibernateProperties(props);
            factoryBean.setAnnotatedClasses(Employee.class);
            return factoryBean;
        }

        @Bean
        public HibernateTransactionManager getTransactionManager() {
            HibernateTransactionManager transactionManager = new HibernateTransactionManager();
            transactionManager.setSessionFactory(getSessionFactory().getObject());
            return transactionManager;
        }
}

7. Last – Create main() method Class File

StartApp.java Class

package com.pt;

import com.pt.configs.AppConfig;
import com.pt.entities.Employee;
import com.pt.services.EmployeeService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.sql.SQLException;

public class StartApp {

    public static void main(String[] args) throws InterruptedException, SQLException {
        System.out.println("This is the start of the PT Spring Hibernate application");
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(AppConfig.class);

        EmployeeService employeeService = context.getBean(EmployeeService.class);

        // Add Employee
        employeeService.add(new Employee(1,"Mak", "S", "mak@pt.com"));

        context.close();
    }
}

OUTPUT

console log

"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" ...
This is the start of the PT Spring Hibernate application
Feb 13, 2020 10:22:46 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.4.11.Final}
Feb 13, 2020 10:22:47 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
Feb 13, 2020 10:22:54 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL57Dialect
Feb 13, 2020 10:22:57 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate: insert into EMPLOYEE (address, first_name, last_name) values (?, ?, ?)

Process finished with exit code 0

In Database – The record is successfully inserted in the database.

mysql> select * from employee;
+----+------------+------------+-----------+
| id | address    | first_name | last_name |
+----+------------+------------+-----------+
|  1 | mak@pt.com | Mak        | S         |
+----+------------+------------+-----------+
1 row in set (0.00 sec)

Summary

In this tutorial, we learnt how to Create a Spring 5 + Hibernate 5 application using Only annotations without xml configuration in really easy way.
Hope you liked it !


Hibernate Entity

What is an Entity in Hibernate? An Entity is a representation of a database table in Java POJO class(Plain old java object).

The Java Persistence API (JPA) is a Java specification that bridges the gap between relational databases and object-oriented programming.

ORM: Object-relational mapping

ORM tools like Hibernate, EclipseLink, and iBatis translate relational database models, including entities and their relationships, into object-oriented models.

Defining Entities

In order to define an entity, you must create a class that is annotated with the following :
1. @Entity : The @Entity annotation is a marker annotation, which is used to discover persistent entities.
2. @Table : If you wanted to map this entity to another table.

Now mapping Fields to Columns

1. @Column : You can override the default mapping by using the @Column annotation.
2. @Id  : to designate a field to be the table’s primary key. The primary key is required to be a Java primitive type, a primitive wrapper, such as Integer or Long, a String, a Date, a BigInteger, or a BigDecimal.

Example :

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   address    VARCHAR(150) default NULL,
   PRIMARY KEY (id)
);

Entity equivalent of the above Database Table

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

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

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

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

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

    public Employee() {}

    public int getId() {
        return id;
    }

    public void setId( int id ) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName( String first_name ) {
        this.firstName = first_name;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName( String last_name ) {
        this.lastName = last_name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

Summary

In this section, we learnt how to create a JPA Entity equivalent of a Database Table. Learnt about ORM object relational mapping.
Hope you liked it !


How to convert String to Date in Java

In this tutorial, we will see how to convert a String into Date in Java, for many developers this is still a challenge so we try to help in making it simple.

// String -> Date
   SimpleDateFormat.parse(String);

// Date -> String
   SimpleDateFormat.format(date);

// In Java 8, String -> Date
   LocalDate localDate = LocalDate.parse(date, formatter);

// In Java 8, Date -> String
   formatter.format(localDate) // DateTimeFormatter

Refer to the table below for Date Time letter Patterns :

LetterDescriptionExamples
yYear2020
MMonth in yearJuly, 07, 7
dDay in month1-31
EDay name in weekFriday, Sunday
aAm/pm markerAM, PM
HHour in day0-23
hHour in am/pm1-12
mMinute in hour0-60
sSecond in minute0-60

Examples

1. String = “7-Jun-2020” to Date “dd-MMM-yyyy”

package com.test.dates;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateUtility {

    public static void main(String[] args) {

        SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");

        String dateInString = "7-Jun-2020";

        try {
            Date date = formatter.parse(dateInString);
            System.out.println(date);
            System.out.println(formatter.format(date)); // returns a String

        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

OUTPUT

Sun Jun 07 00:00:00 IST 2020
07-Jun-2020

2. String = “07182020” to DateMMddyyyy

package com.test.dates;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateUtility {

    public static void main(String[] args) {

        SimpleDateFormat formatter = new SimpleDateFormat("MMddyyyy");

        String dateInString = "07182020";

        try {
            Date date = formatter.parse(dateInString);
            System.out.println(date);
            System.out.println(formatter.format(date)); // returns a String

        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

OUTPUT

Sat Jul 18 00:00:00 IST 2020
07182020

3. In JAVA 8 using LocalDate API, Convert String “dd/MM/yyyy” to LocalDatedd/MM/yyyy

package com.test.dates;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateJava8 {

    public static void main(String[] args) {

      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/MM/yyyy");

      String date = "18/07/2020";

      LocalDate localDate = LocalDate.parse(date, formatter);

      System.out.println(localDate);

      System.out.println(formatter.format(localDate));
    }
}

OUTPUT

2020-07-18
18/07/2020

Summary

In this tutorial, we learnt how to convert String to Date in java using SimpleDateFormat and LocalDate of Java8.
Hope you liked it !