Java Spring Boot (Part 3)

Spring Data JPA

Spring Framework logo by Pivotal Software is licensed under Apache License 2.0

Spring Data JPA

Spring Data JPA provides a set of abstractions and high-level, repository-style interfaces that make it easier to work with Java Persistence API (JPA) for data access in Spring applications. It reduces boilerplate code.

I created a Spring Boot application using Spring Data JPA

I created a new GitHub repository haddley-spring-data-jpa

I opened the repository using GitHub Desktop

I cloned the GitHib repository

GitHub repository folder

I created a new spring boot application springdatajpa

I copied the generated files to the GitHub repository folder

I updated SpringdatajpaApplication.java so that it would respond to http://localhost/hello requests

SpringdatajpaApplication.java
         
package com.haddley.springdatajpa;

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

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

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

    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
        return String.format("Hello %s!", name);
    }
}

I accessed http://localhost/hello using my web browser

I created a TodoItem Java class

TodoItem.java
         
package com.haddley.springdatajpa.models;

import java.time.Instant;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;

import lombok.Getter;
import lombok.Setter;

@Entity
@Table(name = "todo_item")
public class TodoItem {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Getter
    @Setter
    private Long id;

    @Getter
    @Setter
    @NotBlank(message = "Description is required")
    private String description;

    @Getter
    @Setter
    private boolean complete;

    @Getter
    @Setter
    private Instant createdDate;

    @Getter
    @Setter
    private Instant modifiedDate;

    public TodoItem() {}

    public TodoItem(String description) {
        this.description = description;
        this.complete = false;
        this.createdDate = Instant.now();
        this.modifiedDate = Instant.now();
    }

    @Override
    public String toString() {
        return String.format("TodoItem{id=%d, description='%s', complete='%s', createdDate='%s', modifiedDate='%s'}", id, description, complete, createdDate, modifiedDate);
    }


}

I created a Spring Data JPA repository interface (based on the TodoItem class)

TodoItemRepository.java
         
package com.haddley.springdatajpa.models;

import com.haddley.springdatajpa.models.TodoItem;
import org.springframework.data.repository.CrudRepository;

public interface TodoItemRepository extends CrudRepository {
}

I created a TodoItemDataLoader to ensure that if the repository was empty two new TodoItems would be added as the application started

TodoItemDataLoader.java
         
package com.haddley.springdatajpa.config;

import com.haddley.springdatajpa.models.TodoItem;
import com.haddley.springdatajpa.repositories.TodoItemRepository;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class TodoItemDataLoader implements CommandLineRunner {

    private final Logger logger = LoggerFactory.getLogger(TodoItemDataLoader.class);

    @Autowired
    TodoItemRepository todoItemRepository;

    @Override
    public void run(String... args) throws Exception {
        loadSeedData();
    }

    private void loadSeedData() {
        if (todoItemRepository.count() == 0) {
            TodoItem todoItem1 = new TodoItem("get the milk");
            TodoItem todoItem2 = new TodoItem("rake the leaves");

            todoItemRepository.save(todoItem1);
            todoItemRepository.save(todoItem2); 
        }

        logger.info("Number of TodoItems: {}", todoItemRepository.count());
    }

}

I updated SpringdatajpaApplication.java to return all of the TodoItems in response to http://localhost/hello requests

SpringdatajpaApplication.java (updated)
         
package com.haddley.springdatajpa;

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

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.haddley.springdatajpa.models.TodoItem;
import com.haddley.springdatajpa.repositories.TodoItemRepository;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.stream.StreamSupport;
import java.util.stream.Collectors;

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

    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
        return String.format("Hello %s!", name);
    }

    @Autowired
    private TodoItemRepository todoItemRepository;

    @GetMapping("/todos")
    public String index() {

        Iterable todos = todoItemRepository.findAll();

        return StreamSupport.stream(todos.spliterator(), false)
            .map(TodoItem::toString) 
            .collect(Collectors.joining(", ")); 

    }

}

I accessed http://localhost/todos using my web browser

I added text to applications.properties

application.properties
         
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

I accessed the h2 console (using values jdbc:h2:mem:testdb, sa and password)

I clicked on the TODO_ITEM table

I clicked Run to execute the select query

The haddley-spring-data-jpa application hosted in Azure

Accessing the haddley-spring-data-jpa application hosted in Azure