Boot

Spring Boot and JPA Example

Are you keen on learning about using Spring Boot with JPA? Yes? Gather your tools and read on. This example is very straight forward and simple, it should be easy to understand. Let’s begin with our Spring Boot JPA example.

You can also check this tutorial in the following video:

Spring Boot and JPA Example – video

1. Tools

  1. Apache Maven
  2. Mars Eclipse
  3. Spring Boot
  4. Spring Data JPA
  5. H2 Database Engine

2. Assumptions

This article assumes that you know your way around Eclipse. You are familiar with Maven. Familiarity with SQL statements is handy but not required. Basically, you have done some coding. This project has been created using Eclipse Mars so all instructions are based on this IDE.

3. Project Setup

To start, we create our project. This can be done by going to File -> New -> Maven Project and fill up what is required. Alternatively, we can import the Maven project by going to File -> Import… and picking the project.

4. Project Object Model

Our pom.xml should look like the one below:

pom.xml

<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>
  <groupId>com.javacodegeeks.example</groupId>
  <artifactId>spring-boot-jpa</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
  </parent>
  
  <properties>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
      </dependency>
    </dependencies>

    <build>
      <plugins>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
      </plugins>
    </build>
</project>

As shown above, our project has 2 dependencies. We are using spring-boot-starter-data-jpa which means that we can use all the Spring modules included in it. For example, the Spring Core and Spring Data JPA modules will be available for us to use plus many more. The next dependency is the H2 Database Engine. We will be utilizing H2’s in-memory database for this example. In Eclipse, we can see the dependency hierarchy by opening the pom.xml and clicking on the Dependency Hierarchy tab.
The Spring Boot Maven plugin enables us to package the project as an executable jar.

5. Define an Entity

We need to create a Movie object and annotate it as a JPA entity. This object represents a row in the movie table.

Movie.java

package com.javacodegeeks.example;

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

@Entity
public class Movie {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	private String title;
	private String description;

	protected Movie() {
	}

	public Movie(String title, String description) {
		this.title = title;
		this.description = description;
	}

	public Long getId() {
		return id;
	}

	public String getTitle() {
		return title;
	}

	public Movie setDescription(String description) {
		this.description = description;
		return this;
	}

	public String getDescription() {
		return description;
	}

	@Override
	public String toString() {
		return "Movie [id=" + id + ", title=" + title + ", description=" + description + "]";
	}
}

The default constructor exists for JPA and we won’t use it directly. The public constructor is what we’ll use to create instances of Movie to be saved to the database.

The id field is annotated with @Id and GeneratedValue to indicate that it is the object’s ID and to indicate that the ID should be generated automatically.

The title and description fields are assumed to map to columns in the movie table with the same name.

6. Create a Repository Interface

We extend the CrudRepository interface to take advantage of Spring Data’s JPA features. Spring Data JPA focuses on using JPA to store data in a relational database and it has the ability to create repository implementations automatically.

MovieRepository.java

package com.javacodegeeks.example;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface MovieRepository extends CrudRepository<Movie, Long> {

	List<Movie> findByTitle(String title);
}

The generic parameters that CrudRepository works with are of type Movie and Long. Because we extended CrudRepository, we inherit several methods for working with Movie persistence. We are able to create, read, update, and delete Movie entities.

We have also defined our own query method by simply declaring their method signature (findByTitle).

7. Code Walkthrough

Our code below performs the four basic operations of persistent storage. That is create, read, update, delete, in short CRUD. Skim through the code below but peruse the explanation after it.

Main.java

package com.javacodegeeks.example;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main implements CommandLineRunner {
	
	@Autowired
	private MovieRepository movieRepo;
	
	public static void main(String[] args) {
		SpringApplication.run(Main.class, args);
	}
	
	public void run(String... args) throws Exception {
		System.out.println("\nCreating 3 movie records...");
		movieRepo.save(new Movie("Mr. Deeds", "Comedy"));
		movieRepo.save(new Movie("Mad Max Fury Road", "Science Fiction"));
		movieRepo.save(new Movie("We Were Soldiers", "War"));
		
		readRecords();
		
		System.out.println("\nUpdating Mad Max Fury Road record...");
		List<Movie> movies = movieRepo.findByTitle("Mad Max Fury Road");
		Movie madMax = movies.get(0);
		madMax.setDescription("Action/Adventure");
		movieRepo.save(madMax);
		
		readRecords();
		
		System.out.println("\nDeleting Mr. Deeds record...");
		movies = movieRepo.findByTitle("Mr. Deeds");
		Movie mrDeeds = movies.get(0);
		movieRepo.delete(mrDeeds);
		
		readRecords();
	}
	
	private void readRecords() {
		System.out.println("Reading movie records...");
		System.out.printf("%-30.30s  %-30.30s%n", "Title", "Description");
		for (Movie movie : movieRepo.findAll()) {
			System.out.printf("%-30.30s  %-30.30s%n", movie.getTitle(), movie.getDescription());
		}		
	}
}


Instead of annotating our class with @Configuration, @EnableAutoConfiguration, and @ComponentScan, we use the @SpringBootApplication annotation as a convenient alternative. This annotation tells Spring Boot to scan for other components, add beans based on the classpath, and tags the class as a source of bean definitions.

We implemented the CommandLineRunner because we want to execute the run method after the application context is loaded.

Spring Boot automatically creates a MovieRepository because of the @Autowired annotation.

The main method uses SpringApplication.run() to run the application.

Walking through the run method, we first added the movie records using the save method. Did you notice that we did not need to create a table for the records? This was done automatically behind the scenes.

We then used the findAll method to retrieve all the movies in the table. The records are then printed in a nice column.

To update a record, we searched for it based on its title then modify the movie object and saved it back to the repository. The old movie record is overwritten.

The delete method is used for deleting movie records. Similar to the update operation, we searched for the movie based on its title then used that movie object as the argument to the delete method. That movie row is removed from the table.

Did you notice that we did not use any SQL statement? Isn’t that neat? Quickly compare the code above with the Spring Boot JDBC Example. Did you see the difference?

8. Spring Boot JPA Output

After running the code above (Run As -> Java Application), we should have an output that looks like the one below.

Console Output

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.9.RELEASE)

2018-02-17 10:42:52.576  INFO 3464 --- [           main] com.javacodegeeks.example.Main           : Starting Main on asus_k43s with PID 3464 (D:\javacodegeeks_com\spring-boot-jpa\spring-boot-jpa\target\classes started by jpllosa in D:\javacodegeeks_com\spring-boot-jpa\spring-boot-jpa)
2018-02-17 10:42:52.582  INFO 3464 --- [           main] com.javacodegeeks.example.Main           : No active profile set, falling back to default profiles: default
2018-02-17 10:42:52.696  INFO 3464 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1cab0bfb: startup date [Sat Feb 17 10:42:52 GMT 2018]; root of context hierarchy
2018-02-17 10:42:56.728  INFO 3464 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2018-02-17 10:42:56.767  INFO 3464 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
	name: default
	...]
2018-02-17 10:42:56.916  INFO 3464 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
2018-02-17 10:42:56.919  INFO 3464 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2018-02-17 10:42:56.922  INFO 3464 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2018-02-17 10:42:57.201  INFO 3464 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-02-17 10:42:57.517  INFO 3464 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2018-02-17 10:42:59.764  INFO 3464 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000227: Running hbm2ddl schema export
2018-02-17 10:42:59.797  INFO 3464 --- [           main] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete
2018-02-17 10:42:59.869  INFO 3464 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2018-02-17 10:43:01.055  INFO 3464 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup

Creating 3 movie records...
Reading movie records...
Title                           Description                   
2018-02-17 10:43:01.370  INFO 3464 --- [           main] o.h.h.i.QueryTranslatorFactoryInitiator  : HHH000397: Using ASTQueryTranslatorFactory
Mr. Deeds                       Comedy                        
Mad Max Fury Road               Science Fiction               
We Were Soldiers                War                           

Updating Mad Max Fury Road record...
Reading movie records...
Title                           Description                   
Mr. Deeds                       Comedy                        
Mad Max Fury Road               Action/Adventure              
We Were Soldiers                War                           

Deleting Mr. Deeds record...
Reading movie records...
Title                           Description                   
Mad Max Fury Road               Action/Adventure              
We Were Soldiers                War                           
2018-02-17 10:43:01.898  INFO 3464 --- [           main] com.javacodegeeks.example.Main           : Started Main in 10.558 seconds (JVM running for 11.902)
2018-02-17 10:43:01.900  INFO 3464 --- [       Thread-3] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@1cab0bfb: startup date [Sat Feb 17 10:42:52 GMT 2018]; root of context hierarchy
2018-02-17 10:43:01.901  INFO 3464 --- [       Thread-3] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2018-02-17 10:43:01.903  INFO 3464 --- [       Thread-3] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2018-02-17 10:43:01.903  INFO 3464 --- [       Thread-3] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000227: Running hbm2ddl schema export
2018-02-17 10:43:01.910  INFO 3464 --- [       Thread-3] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000230: Schema export complete


The output shows the CRUD operations being performed. We created 3 movie records. We read the movie records from the in-memory database. After that, we updated the “Mad Max Fury Road” description, changing it from “Science Fiction” to “Action/Adventure”. Then we deleted the “Mr. Deeds” movie record. Easy peasy lemon squeezy.

9. Spring Boot JPA Summary

In summary, we include the spring-boot-starter-data-jpa dependency to make available all the Spring modules we need to make JPA operations. We then add the database dependency, in this case H2. We define a JPA entity, in this case a Movie class. Next, we created a repository interface by extending Spring’s CrudRepository. Finally, we wire everything up in the main application class.

10. Download the Source Code

This is an example about Spring Boot JPA.

Download
You can download the source code of this example here: spring-boot-jpa.zip.

Joel Patrick Llosa

I graduated from Silliman University in Dumaguete City with a degree in Bachelor of Science in Business Computer Application. I have contributed to many Java related projects at Neural Technologies Ltd., University of Southampton (iSolutions), Predictive Technologies, LLC., Confluence Service, North Concepts, Inc., NEC Telecom Software Philippines, Inc., and NEC Technologies Philippines, Inc. You can also find me in Upwork freelancing as a Java Developer.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button