In this tutorial, you will learn how to get started with Spring Data JPA step-by-step through a very simple example. No heavy-weight XML or magic Spring Boot stuffs. Just plain Spring way to keep things as simple as possible.

By completing this tutorial, you will be able to understand how to configure a Spring application to use Spring Data JPA, and how simple it is in writing code for manipulating data with Spring Data JPA.

In the sample project below, we will be using Java 8, Eclipse IDE, Hibernate ORM, Spring framework with Spring Data JPA, MySQL database, MySQL Connector Java as JDBC driver.

Suppose that our Java application needs to manage data of the following table:

table customer structure

You can use the following MySQL script to create this table:

CREATE TABLE `customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(45) NOT NULL,
  `lastname` varchar(45) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
And let create a simple Maven project in Eclipse.

 

1. Configure Dependencies in Maven

Open the pom.xml file of the project to specify the required dependencies inside the <dependencies> section.



Since we use the core of Spring framework with support for Spring Data JPA, add the following XML:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-orm</artifactId>
	<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-jpa</artifactId>
	<version>2.1.4.RELEASE</version>
</dependency>
As you can see, we use Spring 5. And for Hibernate framework, we use only its core ORM - so add the following dependency information:

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-core</artifactId>
	<version>5.4.1.Final</version>
</dependency>
And the last dependency we need is JDBC driver for MySQL:

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>8.0.14</version>
</dependency>
Save the pom.xml file, and Maven will automatically download all the required JAR files.


2. Configure Database Connection Properties in persistence.xml

Since Hibernate is used as the provider of JPA (Java Persistence API), we need to specify the database connection properties in the persistence.xml file which is created under the META-INF directory which is under the src/main/resources directory.

Here's the content of the persistence.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
          http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
	version="2.1">
	
	<persistence-unit name="TestDB">
		<properties>
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/testdb" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="password" />
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="hibernate.show_sql" value="true" />
			<property name="hibernate.format_sql" value="true" />
		</properties>
	</persistence-unit>
	
</persistence>
Modify the JDBC URL, user and password accordingly with your MySQL server. Note that the name of the persistence-unit element will be used later in the code.


3. Configure EntityManagerFactory and TransactionManager

Here, we will use Java-based configuration with annotations for a simple Spring application. Create the AppConfig class with the following code:

package net.codejava.spring;

import javax.persistence.EntityManagerFactory;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalEntityManagerFactoryBean;

@Configuration
@EnableJpaRepositories(basePackages = {"net.codejava.spring"})
public class AppConfig {
	@Bean
	public LocalEntityManagerFactoryBean entityManagerFactory() {
		LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();
		factoryBean.setPersistenceUnitName("TestDB");
		
		return factoryBean;
	}
	
	@Bean
	public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
		JpaTransactionManager transactionManager = new JpaTransactionManager();
		transactionManager.setEntityManagerFactory(entityManagerFactory);
		
		return transactionManager;
	}	
}
As you can see, two annotations are specified before the class:

@Configuration
@EnableJpaRepositories(basePackages = {"net.codejava.spring"})
The @Configuration annotation tells Spring to process this class as the source of configuration. And the @EnableJpaRepositories annotation tells Spring to scan for repository classes under the package net.codejava.spring, which we will create one in the next section.

When a repository class is found, Spring will generate an appropriate proxy class at runtime to provide implementation details. So the @EnableJpaRepositories annotation is required to enable Spring Data JPA in a Spring application.

And in this configuration class, we create two important beans: LocalEntityManagerFactoryBean and JpaTransactionManager.

The first one sets up an EntityManagerFactory to work with the persistence unit named TestDB.

And the second one sets up a transaction manager for the configured EntityManagerFactory, in order to add transaction capababilities for respositories. Since we're creating a simple example, we don't use the @EnableTransactionManagement annotation.

 

4. Code Model Class

Create the Customer class with the following code:

package net.codejava.spring;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Customer {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String firstName;
	private String lastName;

	protected Customer() {
	}

	@Override
	public String toString() {
		return "Customer [firstName=" + firstName + ", lastName=" + lastName + "]";
	}	

	// getters and setters are not shown for brevity
}
As you can see, this domain model class is mapped to the table customer in the database using the annotations @Entity, suppose that the table has the same name as the class name.

The @Id and @GeneratedValue annotations map the field id to the primary key column of the table. Suppose that all the fields of the class have same name as the column names in the database table.


5. Code Repository Interface

This is the most interesting part. A repository interface leverages the power of Spring Data JPA. Instead of writing boilerplate code for a generic DAO class (as we would normally do with Hibernate/JPA without Spring Data JPA), we just declare a simple interface like this:

package net.codejava.spring;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface CustomerRepository extends CrudRepository<Customer, Long> {
	List<Customer> findByLastName(String lastName);
}
As you can see, this interface extends the CrudRepository - which is a special interface defined by Spring Data JPA. The type parameter <Customer, Long> specifies the type of the domain model class is Customer and the type of the primary key is Long.

The CrudRepository interface defines common CRUD operations like save(), findAll(), findById(), delete(), count()... Here are the list of methods defined by this interface:

CrudRepository

The interesting thing here is, we don't have to code any implementations for the CustomerRepository interface. We just use the methods defined in the CrudRepositoryinterface which is the super interface of CustomerRepository. At runtime, Spring Data JPA generates the implementation class that takes care all the details.

Note that in the CustomerRepository interface, we can declare findByXXX() methods (XXX is the name of a field in the domain model class), and Spring Data JPA will generate the appropriate code:

List<Customer> findByLastName(String lastName);
This will find all customers whose last name matches the specified lastName in the method's argument. Very convenient!

Spring Data JPA also provides the JpaRepository interface which extends the CrudRepository interface.  JpaRepository defines methods that are specific to JPA.


6. Code Service Class

Next, write a class to make use of the CustomerRepository as follows:

package net.codejava.spring;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("customerService")
public class CustomerService {
	@Autowired
	private CustomerRepository repository;
	
	public void test() {
		// Save a new customer
		Customer newCustomer = new Customer();
		newCustomer.setFirstName("John");
		newCustomer.setLastName("Smith");
		
		repository.save(newCustomer);
		
		// Find a customer by ID
		Optional<Customer> result = repository.findById(1L);
		result.ifPresent(customer -> System.out.println(customer));
		
		// Find customers by last name
		List<Customer> customers = repository.findByLastName("Smith");
		customers.forEach(customer -> System.out.println(customer));
		
		// List all customers
		Iterable<Customer> iterator = repository.findAll();
		iterator.forEach(customer -> System.out.println(customer));
		
		// Count number of customer
		long count = repository.count();
		System.out.println("Number of customers: " + count);
	}
}
As you can see, this class is annotated with the @Service annotation, so Spring framework will create an instance of this class as a managed bean in the application context.

The field CustomerRepositoryrepository is annotated with the @Autowired annotation so Spring Data JPA will automatically inject an instance of CustomerRepositoryinto this service class.

And finally, code the test() method demonstrates some usages of the CustomerRepository.


7. Code Test Program for Spring Data JPA

And finally, write a simple test program as follows:

package net.codejava.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class CustomerTest {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext();
		appContext.scan("net.codejava.spring");
		appContext.refresh();

		CustomerService customerService = (CustomerService) appContext.getBean("customerService");
		customerService.test();

		appContext.close();
	}

}
This program bootstraps Spring framework to scan classes in the net.codejava.spring package. Then it gets the CustomerService bean and invoke its test() method.

Run this program as a normal Java application and observe the result.

For your reference, the project structure looks like this:

SpringDataJPAProjectStructure

And you can also download the sample project in the attachment section below.

 

 

References:

 

Related Spring and Database Tutorials:

 

Other Spring Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Attachments:
Download this file (SpringDataJPASimpleExample.zip)SpringDataJPASimpleExample.zip[Sample Project Code for Spring Data JPA]18 kB

Add comment

   


Comments 

#3joanna della2023-03-23 00:33
There is no way ro make this to work,
Quote
#2Elango2021-07-07 06:25
java.sql.SQLNonTransientConnectionException: CLIENT_PLUGIN_AUTH is required
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110) ~[mysql-connector-java-8.0.15.jar:8.0.15]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.15.jar:8.0.15]
Quote
#1Chithra Kishore2020-08-06 13:05
I am a biggner,I am confused whether it is a dianamic web project or not
Quote