SpringBoot with JPA example

In this tutorial we will learn how to create a basic application using Spring Boot and JPA. We will create the application with Spring Boot CLI, then import it into an IDE to include JPA classes.

Create the Spring Boot application with the CLI

We will start from Spring Command Line Interface. You can however surf to the Spring Initializr Web application if you prefer. – See this tutorial in this regard: Creating a Spring Boot application with Spring Initializr
Within our Web application, named samplewebapp, we will need the following dependencies:

$ spring init -dweb,data-jpa,h2   samplewebapp

Next, let’s check what has been created for us:

~/springboot:$ tree samplewebapp/
samplewebapp/
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── samplewebapp
    │   │               └── DemoApplication.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       └── templates
    └── test
        └── java
            └── com
                └── example
                    └── samplewebapp
                        └── DemoApplicationTests.java

This contains essentially the same project structure as what the Initializr. There is a DemoApplication.java class and a Test class for it:

package com.example.samplewebapp;

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

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

And here is the list of dependencies within the project’s pom.xml file:

<?xml version="1.0" encoding="UTF-8"?><project>
       
   <dependencies>
                       
      <dependency>
                                  
         <groupId>org.springframework.boot</groupId>
                                  
         <artifactId>spring-boot-starter-data-jpa</artifactId>
                          
      </dependency>
                        
      <dependency>
                                  
         <groupId>org.springframework.boot</groupId>
                                  
         <artifactId>spring-boot-starter-web</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>
</project>

Import the Project in your IDE

Next, we will import the Maven project in your IDE – (See this article to learn more about it: Choosing the IDE for Spring Boot development )

As it is, our application won’t do much so let’s add an Entity to our project named Person:

package com.example.samplewebapp;

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

@Entity
public class Person {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  Long id;

  String name;
  String surname;

  public Person(String name, String surname) {
    super();
    this.name = name;
    this.surname = surname;
  }

  public Person() {
    super();
  }

  public Long getId() {
    return id;
  }

  private void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getSurname() {
    return surname;
  }

  public void setSurname(String surname) {
    this.surname = surname;
  }

  @Override
  public String toString() {
    return "Person [id=" + id + ", name=" + name + ", surname=" + surname + "]";
  }
}

One of the coolest features of Spring is the ability to create repository implementations automatically, at runtime, from a repository interface. Out of the box, the repository interface already contains methods to find an Entity by id and to findAll Entity. We will add one more method named “findBySurname” in the following PersonRepository interface:

package com.example.samplewebapp;

import java.util.List;
import org.springframework.data.repository.CrudRepository;

public interface PersonRepository extends CrudRepository<Person, Long> {
  List<Person> findBySurname(String surname);
}

We are done with the backend. Next, we will add in the @SpringBootApplication class some logic to insert a few Entity objects and retrieve them using the repository interface:

package com.example.samplewebapp;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SpringBootApplication public class DemoApplication {
  private static final Logger log = LoggerFactory.getLogger(DemoApplication.class);
  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }
  @Bean public CommandLineRunner demo(PersonRepository repository) {
    return (args) -> { // save a couple of persons
      repository.save(new Person("Jack", "Smith"));
      repository.save(new Person("Joe", "Black"));
      repository.save(new Person("Martin", "Bauer")); 

      // fetch all persons
      log.info("Persons found with findAll():");
      for (Person person: repository.findAll()) {
        log.info(person.toString());
      }
      log.info(""); // fetch an individual person by ID
      repository.findById(1 L).ifPresent(person -> {
        log.info("Person found with findById(1L):");
        log.info("--------------------------------");
        log.info(person.toString());log.info("");
      });
        // fetch persons by last name
        log.info("Person found with findBySurname('Black'):");
        log.info("--------------------------------------------");
        repository.findBySurname("Black").forEach(smith -> {
        log.info(smith.toString());
      });log.info("");
    };
  }
}

As you can see, we have used the CommandLineRunner interface to run the demo. As a matter of fact, Spring Boot provides two interfaces, CommandLineRunner and ApplicationRunner to run specific pieces of code when an application is started. These interfaces get called just before run() once SpringApplication completes. CommandLineRunner, used in our example, provides access to application arguments as string array.

Adding a REST Controller

We can further enhance our application by adding a Controller which will let us check the data available in the repository:

package com.example.samplewebapp;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PersonController {
  @Autowired PersonRepository repository;

  @RequestMapping("/list")
  public List<Person> findAll() {
    List<Person> list = new ArrayList<Person>();
    repository.findAll().iterator().forEachRemaining(list::add);
    return list;
  }

  @RequestMapping("/one/{id}")
  public Optional<Person> findOne(@PathVariable Long id) {
    return repository.findById(id);
  }
}

You can run the application directly from your tool, for example if you are using Eclipse with Spring Tools, right click on the DemoApplication class and choose Run As > SpringBoot app

As an alternative, simply running:

mvn clean install spring-boot:run

or:

java -jar target/samplewebapp-0.0.1-SNAPSHOT.jar

Here is the output provided by the SpringApplication class:

Persons found with findAll():
-------------------------------

Person [id=1, name=Jack, surname=Smith]
Person [id=2, name=Joe, surname=Black]
Person [id=3, name=Martin, surname=Bauer]

Person found with findById(1L):
--------------------------------
Person [id=1, name=Jack, surname=Smith]

Person found with findBySurname('Black'):
--------------------------------------------
Person [id=2, name=Joe, surname=Black]

And you can check it through the available Controller as follows:

curl -s http://localhost:8080/list | jq [   {     "id": 1,     "name": "Jack",     "surname": "Smith"   },   {     "id": 2,     "name": "Joe",     "surname": "Black"   },   {     "id": 3,     "name": "Martin",     "surname": "Bauer"   } ] 

And:

curl -s http://localhost:8080/one/1 | jq {   "id": 1,   "name": "Jack",   "surname": "Smith" } 

In this tutorial we have learned how to develop a basic application using Spring Boot and JPA to store some data and use a repository class to retrieve them.

Source code: https://github.com/fmarchioni/masterspringboot/tree/master/jpa/samplewebapp