DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Data Engineering
  3. Databases
  4. Spring Boot With Spring Data JPA

Spring Boot With Spring Data JPA

Check out this tutorial to get started with Spring Data JPA.

Amit Phaltankar user avatar by
Amit Phaltankar
·
Feb. 11, 19 · Presentation
Like (26)
Save
Tweet
Share
221.99K Views

Join the DZone community and get the full member experience.

Join For Free

Welcome to the Spring Boot with Spring Data JPA tutorial! In this tutorial, we are going to see how Spring Data JPA provides complete abstraction over the DAO layer. We don’t need to write the implementation for the DAO layer anymore; Spring Data auto-generates the implementation DAO implementations.

We already had an introduction to Spring Boot, and for this tutorial, we will use Spring Boot along with Spring Data. You will also see how Spring Boot auto-configuration helps to get data source configurations done, hassle-free.

In our tutorial Spring Boot Rest Service, we created a DogService, which included a simple CRUD service based on the Mock Data Provider. We will use the same DogService and replace the Mock Data Provider with the actual MySQL database along with Spring Data and JPA.

Dependency Configuration

In this tutorial, I am using a MySQL database along with Spring Data. Here is the build.gradle file:

buildscript {
    ext {
        springBootVersion = '2.1.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.amitph.spring'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile('mysql:mysql-connector-java:8.0.13')

    testImplementation('org.springframework.boot:spring-boot-starter-test')
}


Learn more about JPA and Spring Data JPA here:

  • Java Persistence API Guide
  • Spring Data JPA – Query Methods
  • Pagination and Sorting with Spring Data JPA
  • Spring Data JPA Composite Key with @EmbeddedId

Datasource Configuration

We now have dependencies configured. It is not time to tell which data source to connect to. Here is my application.yml with Spring Boot data source entries.

spring:
  datasource:
    url: jdbc:mysql://localhost:33099/dogs
    password: <ENTER _ PASSWORD _ HERE >
    username: root
    driver-class-name: "com.mysql.jdbc.Driver"
  jpa:
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    hibernate:
      ddl-auto: update


Here, we have the specified JDBC URL, username, password, and driver class name (MySQL).
Apart from this, there are JPA specific configurations. First is the database-platform, which tells us the underlying Hibernate features to consider under the MySQL query dialect. This is so that all the database operations will be handled in MySQL specific syntax. The second JPA configuration is ddl-auto, which tells Hibernate to create the respective database and table structure, if not already present.

When this option is turned on, Hibernate will create the database structure based on the Entity Beans and the data source.

Entity Bean

The first code level thing we will do is write an Entity Bean. Here is what the Oracle Documentation says about Entity Beans.

Using JPA, you can designate any POJO class as a JPA entity – a Java object whose nontransient fields should be persisted to a relational database using the services of an entity manager obtained from a JPA persistence provider (either within a Java EE EJB container or outside of an EJB container in a Java SE application).

In simpler words, the JPA Entity is any Java POJO, which can represent the underlying table structure. As our service is based on theDog table, we will create a Dog Entity object.

package com.amitph.spring.dogs.repo;

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

@Entity
public class Dog {
    @Id
    @GeneratedValue
    private long id;
    private String name;
    private int age;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}


The above POJO is annotated with @Entity, which is to denote this is an entity object for the table name Dog.

Then, there are three fields that represent the datable table columns. Field id is our Primary Key and, hence, marked as @Id.

The field id is also marked with @GeneratedValue, which denotes that this is an Auto-Increment column and Hibernate will take care of putting in the next value. Hibernate will first query the underlying table to know the max value of the column and increment it with next insert. This also means that we don’t need to specify any value for the Id column and can leave it blank.

Repository Interface

The Repository represents the DAO layer, which typically does all the database operations. Thanks to Spring Data, who provides the implementations for these methods. Let’s have a look at our DogsRepoisitory, which extends the CrudRepository:

package com.amitph.spring.dogs.repo;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface DogsRepository extends CrudRepository<Dog, Long> {}


There are no method declarations here in the DogsRepository. That is because Spring Data’s CrudInterface has already declared basic CRUD methods.

Here, we are done with the JPA and Spring data things — in other words, the DAO layer. Let’s now write a simple Service Layer and a Controller.

Controller and Service Layer

As we have our data access layer done, we will write our controller and service layer. Notice that the DogsRepository is annotated with @Repository, which also adds it to the Spring Context. We can now Autowire the repository in Service.

Dogs Service

This class has simple CRUD methods. It also converts the Entity bean to a DTO (data transfer object). DTO is also a simple Java POJO, which is used to transfer data between systems. Here, we are returning DTOs from our REST endpoints.

package com.amitph.spring.dogs.service;

import com.amitph.spring.dogs.model.DogDto;
import com.amitph.spring.dogs.repo.Dog;
import com.amitph.spring.dogs.repo.DogsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

@Component
public class DogsService {
    @Autowired DogsRepository repository;

    public void add(DogDto dto) {
        repository.save(toEntity(dto));
    }

    public void delete(long id) {
        repository.deleteById(id);
    }

    public List<Dog> getDogs() {
        return (List<Dog>) repository.findAll();
    }

    public Dog getDogById(long id) {
        Optional<Dog> optionalDog = repository.findById(id);
        return optionalDog.orElseThrow(() -> new DogNotFoundException("Couldn't find a Dog with id: " + id));
    }

    private Dog toEntity(DogDto dto) {
        Dog entity = new Dog();
        entity.setName(dto.getName());
        entity.setAge(dto.getAge());
        return entity;
    }
}


Dogs Controller

The Dogs Controller is a standard REST controller with simple CRUD endpoints. The job of the controller is to handle the HTTP requests and invoke the Service class methods.

package com.amitph.spring.dogs.web;

import com.amitph.spring.dogs.model.DogDto;
import com.amitph.spring.dogs.repo.Dog;
import com.amitph.spring.dogs.service.DogsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/dogs")
public class DogsController {
    @Autowired DogsService service;

    @GetMapping
    public List<Dog> getDogs() {
        return service.getDogs();
    }

    @PostMapping
    public void postDogs(@RequestBody DogDto dto) {
        service.add(dto);
    }

    @GetMapping("/{id}")
    public Dog getById(@PathVariable(required = true) long id) {
        return service.getDogById(id);
    }

    @DeleteMapping("/{id}")
    public void delete(@PathVariable(required = true) long id) {
        service.delete(id);
    }
}


Now, the Dogs Service is ready to run. Start the application and execute the HTTP endpoints — that’s it.

Conclusion

This is the end of our Spring Boot with Spring data and JPA tutorial. We saw how to use Spring Data’s abstraction for the Data Access Layer. We saw how to represent a database table in the form of Entity Bean and how to Use Spring Data’s autogenerated repository implementations. Additionally, we also saw how to use Spring Boot to conduct automatic datasource configurations.

In the Spring Boot Rest Service post, we have already seen creating a RESTful web service with Spring Boot. In the current article, we did not care about Exception Handling. Visit Spring Rest Service Exception Handling to learn about handling exceptions. We also skipped the unit testing part here, which will be covered in upcoming articles.

For the full source code and examples used here, please visit https://github.com/amitrp/dog-service-jpa.

Spring Framework Spring Data Spring Boot Data (computing) Database Relational database

Published at DZone with permission of Amit Phaltankar. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Secure APIs: Best Practices and Measures
  • When to Choose Redpanda Instead of Apache Kafka
  • 5 Software Developer Competencies: How To Recognize a Good Programmer
  • Reliability Is Slowing You Down

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: