Spring Data JPA Example + Spring Boot

By Dhiraj Ray, 15 March,2017   | Last updated on: 16 March,2018 6K

In this tutorial we will take a look into spring data jpa in detail. We will see integratation between spring data and spring boot with examples. We will perform different crud operations using spring data and check out different ways and advantages of using it. We will have some REST endpoints exposed through spring controller and we will be invoking these endpoints to perform different crud operations. We will also take a look into how to make use of entitymanager and hibernate session in spring data. If you are looking for spring boot hibernate example then visit here - spring boot hibernate example

Table of Contents
1. Why Spring Data 
2. What is Spring Data JPA
3. Different Spring Data Repositories
4. Project Structure
5. Maven Dependencies
6. Spring Boot Config
6.1 Spring Application Class
7. JPA Datasource Configurations
7.1 Hikari Datasource Configurations
8.1 JPA Entity
8.2 Defining Spring Controller
8.3 Defining Service class
8.4 Defining DAO class
9. Database Scripts
10. Spring Boot 2 and JPA
11. Run Application

Why Spring Data

Spring data simplifies the data access operations to a very greater extent. The most compelling feature of spring data is the ability to create repository implementations automatically, at runtime, from a repository interface. Hence, you only define the dao interface and the operations you want to perform such as save, read, delete and spring data will provide the implementations at runtime. Not only this, it also provides many inbuilt features for paginations, querying, auditing etc. Spring data provides support for both relational and NoSql DB.

What is Spring Data JPA

Among the many modules provided by Spring Data such as Spring Data Solr, Spring Data MongoDB, Spring Data REST to deal with the persistence layer, Spring Data JPA is also a sub project to deal with persisitence layer. Spring data provides enhanced support for JPA based implementations. We only require to define our repository interfaces, including custom finder methods, and Spring will provide the implementation automatically at run-time.

Different Spring Data Repositories

Lets discuss about different interfaces provided by spring data JPA to deal with persistence layer.

Repository - It is the central interface in the spring data repository abstraction. This is defined as a marker interface.

CrudRepository - CrudRepository provides methods such as save(), findOne(), findAll(), delete() etc. for the CRUD operations. This interface extends the Repository interface. While creating our dao interface we extend this interface with our custom interface and just invoke the abstract methods defined in CrudRepository and spring data will take care of providing the corresponding implementations at run-time.

JpaRepository - It is a JPA specific extension of Repository. It extends CrudRepository and provides some extra JPA related method such as flushing the persistence context and delete record in a batch.

PagingAndSortingRepository - It also extends CrudRepository provide methods to do pagination and sorting records.

Project Structure

Let us first define the project structure.

spring-boot-data-example-strct

Maven Dependencies

spring-boot-starter-parent: It provides useful Maven defaults. It also provides a dependency-management section so that you can omit version tags for existing dependencies.

spring-boot-starter-web: It includes all the dependencies required to create a web app. This will avoid lining up different spring common project versions.

spring-boot-starter-tomcat: It enable an embedded Apache Tomcat 7 instance, by default.This can be also marked as provided if you wish to deploy the war to any other standalone tomcat.

spring-boot-starter-tomcat: It provides key dependencies for Hibernate, Spring Data JPA and Spring ORM.

pom.xml
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>
	
    <dependencies>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
			<exclusions>
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-jdbc</artifactId>
                </exclusion>
            </exclusions>
		</dependency>
		<dependency>
            <groupId>mysql</groupId>
            &tartifactId>mysql-connector-java</artifactId>
        </dependency>
		<dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
		</dependency>
		
    </dependencies>
	

Spring Boot Config

Spring Application class

@SpringBootApplication enables many defaults. It is a convenience annotation that adds @Configuration, @EnableAutoConfiguration, @EnableWebMvc, @ComponentScan

The main() method uses Spring Boot SpringApplication.run() method to launch an application.

Application.java
package com.devglan;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Other Interesting Posts
Spring Boot Hibernate 5 Example
Spring Hibernate Integration Example
Spring Boot Actuator Rest Endpoints Example
Spring 5 Features and Enhancements
Spring Boot Thymeleaf Example
Securing REST API with Spring Boot Security Basic Authentication
Spring Boot Security Password Encoding using Bcrypt Encoder
Spring Security with Spring MVC Example Using Spring Boot
Websocket spring Boot Integration Without STOMP with complete JavaConfig

JPA Datasource Configuration

Following is our sample datasource configuration. Spring boot automatically identifies the driver class name with the help of datasource url.

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root

Hikari Datasource Configurations

In production, it is always recommended to use datasource that supports connection pooling because database connection creation is a slow process.Here in the example we will be using HikariDatasource instead. It provides many advanced features while configuring our datasource in comparison to other datasources such as connectionTimeout, idleTimeout, maxLifetime, connectionTestQuery, maximumPoolSize and very important one is leakDetectionThreshold.It is as advanced as detecting connection leaks by itself.It is also faster and lighter than other available datasource.Following is the configuration for HikariDatasource.Make sure you comment the datasource confguration in properties file.

HikariDatasource Config
@Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setMaximumPoolSize(100);
        ds.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
        ds.addDataSourceProperty("url", "jdbc:mysql://localhost:3306/test");
        ds.addDataSourceProperty("user", "root");
        ds.addDataSourceProperty("password", "password");
        ds.addDataSourceProperty("cachePrepStmts", true);
        ds.addDataSourceProperty("prepStmtCacheSize", 250);
        ds.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
        ds.addDataSourceProperty("useServerPrepStmts", true);
        return ds;
    }

We can also create Hikaridatasource using DataSourceBuilder as follow.While doing so the datasource related properties can be still there in proerties file.I like this way.

@Bean
@ConfigurationProperties("spring.datasource")
public HikariDataSource dataSource() {
	return DataSourceBuilder.create().type(HikariDataSource.class).build();
}

In order to use HikariDataSource, you must include following maven dependency. Checkout the latest version here - Hikari Maven

<dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
			<version>2.7.3</version>
			</dependency>

In this case, we need to explicitly tell spring boot to use our custom datasource while creating EntityManagerfactory.Following is a sample example.

@Bean(name = "entityManagerFactory")
public EntityManagerFactory entityManagerFactory() {
	LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
	emf.setDataSource(dataSource);
	emf.setJpaVendorAdapter(jpaVendorAdapter);
	emf.setPackagesToScan("com.mysource.model");
	emf.setPersistenceUnitName("default");
	emf.afterPropertiesSet();
	return emf.getObject();
}

Server Side implementation

Entity Class

Following is the entity class.

UserDetails.java
package com.devglan.model;

@Entity
@Table
public class UserDetails {
	
	@Id
	@Column
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	@Column
	private String firstName;
	@Column
	private String lastName;
	@Column
	private String email;
	@Column
	private String password;
	
	//getters and setters goes here
	

Defining Spring Controller

Following is the controller class. It exposes rest endpoints for our crud operations.

@Controller
@RequestMapping("/user")
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ResponseEntity> userDetails() {
        
		List userDetails = userService.getUserDetails();
		return new ResponseEntity>(userDetails, HttpStatus.OK);
	}

	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public ResponseEntity findById(@PathVariable(name = "id", value = "id") Long id) {

		UserDetails userDetail = userService.findById(id);
		return new ResponseEntity(userDetail, HttpStatus.OK);
	}

	@RequestMapping(method = RequestMethod.POST)
	public ResponseEntity findById(@RequestBody UserDetails userDetails) {

		UserDetails userDetail = userService.save(userDetails);
		return new ResponseEntity(userDetail, HttpStatus.OK);
	}

	@RequestMapping(value = "/email/{email:.+}", method = RequestMethod.GET)
	public ResponseEntity findById(@PathVariable(name = "email", value = "email") String email) {

		UserDetails userDetail = userService.findByEmail(email);
		return new ResponseEntity(userDetail, HttpStatus.OK);
	}

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public ResponseEntity delete(@PathVariable(name = "id", value = "id") Long id) {

        userService.delete(id);
        return new ResponseEntity("success", HttpStatus.OK);
    }
}

Defining Service class

Following is the service class that acts as a bridge between controller and dao.

@Service
public class UserServiceImpl implements UserService {
	
	@Autowired
	private UserDao userDao;

	@Override
	public List getUserDetails() {
		return (List) userDao.findAll();
	}

	@Override
	public UserDetails findById(Long id) {
		return  userDao.findOne(id);
	}

	@Override
	public UserDetails save(UserDetails user) {
		return  userDao.save(user);
	}

	@Override
	public UserDetails findByEmail(String email) {
		return  userDao.findByEmail(email);
	}

	@Override
	public void delete(Long id) {
		userDao.delete(id);
	}
}

Defining DAO class

The UserDao interface extends CrudRepository which has different crud methods such as create, findOne, delete etc and hence our UserDao automatically inherits them which is available for our service class to use. Its spring data which will generate the implementations at run time for these crud methods. Hence, we dont have to provide the implementations.

Notice the generic parameters in CrudRepository. Based on these parameters, Spring data will perform different crud operations at run time on our behalf.

Apart from the different default methods defined in the CrudRepository, we have defined our own method - findByEmail(). We have one parameter defined in our entiry class as email and by the naming conventions as findByEmail, Spring data will automatically identify that this is a search operation by email of the user.

public interface UserDao extends CrudRepository {
	
	UserDetails findByEmail(String email);
	
}

Spring data is not limited to use of only JPA and some standards methods. Even it is possible to define some custom methods and custom operations too. You can also make use of JPA provided entitymanager to perform custom data manipulation as well as use hibernate session to make advanatage of different functions provided by hibernate.

Using EntityManager in Spring Data

Following is the implementation that uses entitymanager to save data in db while using spring data.

@Repository
public class UserDaoImpl implements Userdao {
	
	@PersistenceContext
    private EntityManager entityManager;

    @Override
    public void save(UserDetails user) {
        entityManager.persist(user);
    }
	
}

Using Hibernate Session in Spring Data

As we discussed, Spring data is not only limited to use of JPA, you can also make use of hibernate session and make use of different functions provided by hibernate.

@Repository
public class UserDaoImpl implements UserDao {
	
    @PersistenceContext
    private EntityManager entityManager;

	public List getUserDetails() {
		Criteria criteria = entityManager.unwrap(Session.class).createCriteria(UserDetails.class);
		return criteria.list();
	}

}

Spring Boot 2 and JPA

Above configurations works well with spring boot version lessa then 2 but with the release of spring boot 2.0 we do not require any explicit configuration for Hikari datasource. Spring Boot 2 JPA has by default support for Hikari connection pooling. Hence, in the above configuration, remove the artifact of commons-dbcp and hikari artifact and with the rest of the configuration remaining same we can have Hikari connection pooling.

There are conventional methods removed for pagination and sorting.For example new PageRequest() is deprecated.Following is an example to use Pageable in spring data JPA.The following method can either return the list or org.springframework.data.domain.Page

@Repository
public interface UserPageableDao extends PagingAndSortingRepository {

    //List listUsers(Pageable pageable);
    Page listUsers(Pageable pageable);
}

From service implementation we can invoke this DAO method as below:

public List getUserDetails1() {
        Pageable pageable = PageRequest.of(0, 3, Sort.Direction.DESC,"createdOn");
        Page page = userPageableDao.listUsers(pageable);
        return page.getContent();
    }
	
//findOne() is removed.
@Override
public UserDetails findById(Long id) {
	return  userDao.findById(id).get();
}

//delete(id) is removed
@Override
public void delete(Long id) {
	userDao.deleteById(id);
}

Database Scripts

Following are some sample DML. We will be creating some dummy user details using following insert statements.

create table User_Details (id integer not null auto_increment, email varchar(255), first_Name varchar(255), last_Name varchar(255), password varchar(255), primary key (id)) ENGINE=InnoDB;

INSERT INTO user_details(email,first_Name,last_Name,password) VALUES ('admin@admin.com','admin','admin','admin');

INSERT INTO user_details(email,first_Name,last_Name,password) VALUES ('john@gmail.com','john','doe','johndoe');

INSERT INTO user_details(email,first_Name,last_Name,password) VALUES ('sham@yahoo.com','sham','tis','shamtis');

Run Application

1. Run Application.java as a java application.

+

2. Now hit the url - localhost:8080/user/list and you can see following.

spring-boot-data-example-list

3. You can also try for post request using postman or ARC as follow:

spring-boot-data-post-request

Similarly you can make other requests.

Conclusion

I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Download the source

Further Reading on Spring Boot

1. Hibernate Naming Strategy

2. Spring Boot Multiple Database Configuration

3. Spring Boot H2 Database Example

4. Spring Boot Hibernate 5 Example

5. Spring Boot Actuator Rest Endpoints Example

If You Appreciate What We Do Here On Devglan, You Should Consider:

References

Spring data JPA

Accessing data JPA

JPA repositories

spring Boot Datasource

Data Access