This guide walks you through the process of building an application that uses Spring Data JPA to store and retrieve data in a relational database.

What you’ll build

You’ll build an application that stores Customer POJOs in a memory-based database.

What you’ll need

How to complete this guide

Like most Spring Getting Started guides, you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.

To start from scratch, move on to Set up the project.

To skip the basics, do the following:

When you’re finished, you can check your results against the code in gs-accessing-data-jpa/complete.

Set up the project

First you set up a basic build script. You can use any build system you like when building apps with Spring, but the code you need to work with Gradle and Maven is included here. If you’re not familiar with either, refer to Building Java Projects with Gradle or Building Java Projects with Maven.

Create the directory structure

In a project directory of your choosing, create the following subdirectory structure; for example, with mkdir -p src/main/java/hello on *nix systems:

└── src
    └── main
        └── java
            └── hello

Create a Gradle build file

Below is the initial Gradle build file. But you can also use Maven. The pom.xml file is included right here. If you are using Spring Tool Suite (STS), you can import the guide directly.

If you look at pom.xml, you’ll find it has a specific version of maven-compiler-plugin. This is NOT recommended in general. Instead, it’s meant to solve an issue with our CI system that defaulted to a very old (pre-Java5) version of this plugin. build.gradle
buildscript {
    repositories {
        maven { url "" }
    dependencies {

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'gs-accessing-data-jpa'
    version =  '0.1.0'

repositories {
    maven { url "" }
    maven { url "" }

dependencies {

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'

The Spring Boot gradle plugin provides many convenient features:

  • It collects all the jars on the classpath and builds a single, runnable "über-jar", which makes it more convenient to execute and transport your service.

  • It searches for the public static void main() method to flag as a runnable class.

  • It provides a built-in dependency resolver that sets the version number to match Spring Boot dependencies. You can override any version you wish, but it will default to Boot’s chosen set of versions.

Define a simple entity

In this example, you store Customer objects, annotated as a JPA entity.


package hello;

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

public class Customer {

    private long id;
    private String firstName;
    private String lastName;

    protected Customer() {}

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;

    public String toString() {
        return String.format(
                "Customer[id=%d, firstName='%s', lastName='%s']",
                id, firstName, lastName);


Here you have a Customer class with three attributes, the id, the firstName, and the lastName. You also have two constructors. The default constructor only exists for the sake of JPA. You won’t use it directly, so it is designated as protected. The other constructor is the one you’ll use to create instances of Customer to be saved to the database.

In this guide, the typical getters and setters have been left out for brevity.

The Customer class is annotated with @Entity, indicating that it is a JPA entity. For lack of a @Table annotation, it is assumed that this entity will be mapped to a table named Customer.

The Customer's id property is annotated with @Id so that JPA will recognize it as the object’s ID. The id property is also annotated with @GeneratedValue to indicate that the ID should be generated automatically.

The other two properties, firstName and lastName are left unannotated. It is assumed that they’ll be mapped to columns that share the same name as the properties themselves.

The convenient toString() method will print out the customer’s properties.

Create simple queries

Spring Data JPA focuses on using JPA to store data in a relational database. Its most compelling feature is the ability to create repository implementations automatically, at runtime, from a repository interface.

To see how this works, create a repository interface that works with Customer entities:


package hello;

import java.util.List;


public interface CustomerRepository extends CrudRepository<Customer, Long> {

    List<Customer> findByLastName(String lastName);

CustomerRepository extends the CrudRepository interface. The type of entity and ID that it works with,Customer and Long, are specified in the generic parameters on CrudRepository. By extending CrudRepository, CustomerRepository inherits several methods for working with Customer persistence, including methods for saving, deleting, and finding Customer entities.

Spring Data JPA also allows you to define other query methods by simply declaring their method signature. In the case of CustomerRepository, this is shown with a findByLastName() method.

In a typical Java application, you’d expect to write a class that implements CustomerRepository. But that’s what makes Spring Data JPA so powerful: You don’t have to write an implementation of the repository interface. Spring Data JPA creates an implementation on the fly when you run the application.

Let’s wire this up and see what it looks like!

Create an Application class

Here you create an Application class with all the components.


package hello;

import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;

public class Application {

    public static void main(String[] args) {

        ConfigurableApplicationContext context =;
        CustomerRepository repository = context.getBean(CustomerRepository.class);

        // save a couple of customers Customer("Jack", "Bauer")); Customer("Chloe", "O'Brian")); Customer("Kim", "Bauer")); Customer("David", "Palmer")); Customer("Michelle", "Dessler"));

        // fetch all customers
        Iterable<Customer> customers = repository.findAll();
        System.out.println("Customers found with findAll():");
        for (Customer customer : customers) {

        // fetch an individual customer by ID
        Customer customer = repository.findOne(1L);
        System.out.println("Customer found with findOne(1L):");

        // fetch customers by last name
        List<Customer> bauers = repository.findByLastName("Bauer");
        System.out.println("Customer found with findByLastName('Bauer'):");
        for (Customer bauer : bauers) {



In the configuration, you need to add the @EnableAutoConfiguration annotation. This annotation tells Spring Boot to configure JPA repositories and entities from the current package. So any interface that extends will automatically have an implementation generated. By extending JpaRepository, your CustomerRepository interface transitively extends Repository. Therefore, Spring Data JPA will find it and create an implementation for you.

Application includes a main() method that puts the CustomerRepository through a few tests. First, it fetches the CustomerRepository from the Spring application context. Then it saves a handful of Customer objects, demonstrating the save() method and setting up some data to work with. Next, it calls findAll() to fetch all Customer objects from the database. Then it calls findOne() to fetch a single Customer by its ID. Finally, it calls findByLastName() to find all customers whose last name is "Bauer".

Build an executable JAR

You can build a single executable JAR file that contains all the necessary dependencies, classes, and resources. This makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.

./gradlew build

Then you can run the JAR file:

java -jar build/libs/gs-accessing-data-jpa-0.1.0.jar

If you are using Maven, you can run the application using mvn spring-boot:run. Or you can build the JAR file with mvn clean package and run the JAR by typing:

java -jar target/gs-accessing-data-jpa-0.1.0.jar
The procedure above will create a runnable JAR. You can also opt to build a classic WAR file instead.

Run the service

If you are using Gradle, you can run your service at the command line this way:

./gradlew clean build && java -jar build/libs/gs-accessing-data-jpa-0.1.0.jar
If you are using Maven, you can run your service by typing mvn clean package && java -jar target/gs-accessing-data-jpa-0.1.0.jar.

You can alternatively run the app directly from Gradle like this:

./gradlew bootRun
With mvn, you can run mvn spring-boot:run.

You should see something like this:

== Customers found with findAll():
Customer[id=1, firstName='Jack', lastName='Bauer']
Customer[id=2, firstName='Chloe', lastName='O'Brian']
Customer[id=3, firstName='Kim', lastName='Bauer']
Customer[id=4, firstName='David', lastName='Palmer']
Customer[id=5, firstName='Michelle', lastName='Dessler']

== Customer found with findOne(1L):
Customer[id=1, firstName='Jack', lastName='Bauer']

== Customer found with findByLastName('Bauer'):
Customer[id=1, firstName='Jack', lastName='Bauer']
Customer[id=3, firstName='Kim', lastName='Bauer']


Congratulations! You’ve written a simple application that uses Spring Data JPA to save objects to a database and to fetch them — all without writing a concrete repository implementation.

If you’re interesting in exposing JPA repositories with a hypermedia-based RESTful front end with little effort, you might want to read Accessing JPA Data with REST.