Spring Framework logo by Pivotal Software is licensed under Apache License 2.0
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