Learn to configure hibernate/JPA support in Spring Boot2 applications, along with creating entity classes and extending inbuilt JpaRepository interfaces.
In this example, we are using maven to add runtime jars in project. If you are using gradle then please find related dependencies.
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.howtodoinjava.demo</groupId>
<artifactId>SpringBoot2Demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBoot2Demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
file, we are using h2 database in reduce unnecessary complexity.After we have included required jars in classpath, create few entity classes as per project needs. We are here creating one such entity EmployeeEntity for example purpose.
Remember to include only JPA API annotations (javax.persistence.*
) to decouple hibernate from application code.
EmployeeEntity.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="TBL_EMPLOYEES")
public class EmployeeEntity {
@Id
@GeneratedValue
private Long id;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="email", nullable=false, length=200)
private String email;
//Setters and getters left out for brevity.
@Override
public String toString() {
return "EmployeeEntity [id=" + id + ", firstName=" + firstName +
", lastName=" + lastName + ", email=" + email + "]";
}
}
EmployeeEntity
. We can customize the table name using @Table annotation and it’s name
attribute.id
property is annotated with @Id
so that JPA will recognize it as the object’s ID. Also, @GeneratedValue
annotation enable its value generated automatically.null
value allowed or size of column etc. use @Column
annotation.toString()
method to print employee’s basic details in logs.Extend <a href="https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html" target="_blank">JpaRepository</a>
interface to allows to create repository implementations automatically, at runtime, for any given entity class. The types of entity class and it’s ID field are specified in the generic parameters on JpaRepository
.
EmployeeRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.howtodoinjava.demo.entity.EmployeeEntity;
@Repository
public interface EmployeeRepository extends JpaRepository<EmployeeEntity, Long> {
}
By this simple extension, EmployeeRepository
inherits several methods for working with Employee
persistence, including methods for saving, deleting, and finding Employee
entities.
Along with default provided methods, we can add our own custom methods and queries to this interface.
Provide the datasource connection properties in application.properties
file which will help in connecting the database to JPA code.
In given config, we are configuring h2 database.
application.properties
spring.datasource.url=jdbc:h2:file:~/test
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# Enabling H2 Console
spring.h2.console.enabled=true
# Custom H2 Console URL
spring.h2.console.path=/h2-console
A good way to see how the components are working – is to enable extensive logging. Do it when it’s too easy using only few properties entries.
application.properties
#Turn Statistics on and log SQL stmts
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
#If want to see very extensive logging
spring.jpa.properties.hibernate.generate_statistics=true
logging.level.org.hibernate.type=trace
logging.level.org.hibernate.stat=debug
In a JPA-based applications, we can either choose to let Hibernate create the schema using entity classes or use schema.sql
, but we cannot do both.
Make sure to disable spring.jpa.hibernate.ddl-auto if using schema.sql
.
application.properties
#Schema will be created using schema.sql and data.sql files
spring.jpa.hibernate.ddl-auto=none
schama.sql
DROP TABLE IF EXISTS TBL_EMPLOYEES;
CREATE TABLE TBL_EMPLOYEES (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(250) NOT NULL,
last_name VARCHAR(250) NOT NULL,
email VARCHAR(250) DEFAULT NULL
);
data.sql
INSERT INTO TBL_EMPLOYEES
(first_name, last_name, email)
VALUES
('Lokesh', 'Gupta', 'abc@gmail.com'),
('Deja', 'Vu', 'xyz@email.com'),
('Caption', 'America', 'cap@marvel.com');
To test hibernate configuration with Spring boot, we need to autowire the EmployeeRepository
dependency in a class and use it’s method to save or fetch employee entities.
Let’s do this testing in @SpringBootApplication
annotated class and using <a href="https://howtodoinjava.com/spring-boot/command-line-runner-interface-example/" target="_blank">CommandLineRunner</a>
interface. The run()
method from CommandLineRunner
is executed immediately after the application startup.
SpringBoot2DemoApplication.java
package com.howtodoinjava.demo;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.howtodoinjava.demo.entity.EmployeeEntity;
import com.howtodoinjava.demo.repository.EmployeeRepository;
@SpringBootApplication
public class SpringBoot2DemoApplication implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
EmployeeRepository repository;
public static void main(String[] args) {
SpringApplication.run(SpringBoot2DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception
{
Optional<EmployeeEntity> emp = repository.findById(2L);
logger.info("Employee id 2 -> {}", emp.get());
}
}
Run the application and observe the output. Please note that to print limited information in logs, I am using property logging.pattern.console=%m%n in application
Console
Tomcat initialized with port(s): 8080 (http)
Starting service [Tomcat]
Starting Servlet engine: [Apache Tomcat/9.0.19]
Initializing Spring embedded WebApplicationContext
Root WebApplicationContext: initialization completed in 5748 ms
HikariPool-1 - Starting...
HikariPool-1 - Start completed.
HHH000204: Processing PersistenceUnitInfo [
name: default
...]
HHH000412: Hibernate Core {5.3.10.Final}
HHH000206: hibernate.properties not found
HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Initialized JPA EntityManagerFactory for persistence unit 'default'
Initializing ExecutorService 'applicationTaskExecutor'
spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering.
Explicitly configure spring.jpa.open-in-view to disable this warning
Tomcat started on port(s): 8080 (http) with context path ''
Started SpringBoot2DemoApplication in 17.638 seconds (JVM running for 19.1)
Hibernate:
select
employeeen0_.id as id1_0_0_,
employeeen0_.email as email2_0_0_,
employeeen0_.first_name as first_na3_0_0_,
employeeen0_.last_name as last_nam4_0_0_
from
tbl_employees employeeen0_
where
employeeen0_.id=?
Employee id 2 -> EmployeeEntity [id=2, firstName=Deja, lastName=Vu, email=xyz@email.com]
Clearly, hibernate has been configured and we are able to interact with database using JPA repository interface.
Drop me your questions in comments sections related to configuring hibernate with spring boot.
#spring-boot #hibernate #java