diff --git a/persistence-modules/spring-boot-persistence-3/HELP.md b/persistence-modules/spring-boot-persistence-3/HELP.md
new file mode 100644
index 0000000000..d5a5463718
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/HELP.md
@@ -0,0 +1,9 @@
+# Getting Started
+
+### Reference Documentation
+For further reference, please consider the following sections:
+
+* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
+* [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#using-boot-devtools)
+* [Spring Configuration Processor](https://docs.spring.io/spring-boot/docs/{bootVersion}/reference/htmlsingle/#configuration-metadata-annotation-processor)
+
diff --git a/persistence-modules/spring-boot-persistence-3/README.md b/persistence-modules/spring-boot-persistence-3/README.md
new file mode 100644
index 0000000000..1dff3c8b5a
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- More articles: [[<-- prev]](../spring-boot-persistence-2)
diff --git a/persistence-modules/spring-boot-persistence-3/pom.xml b/persistence-modules/spring-boot-persistence-3/pom.xml
new file mode 100644
index 0000000000..b9d9d8b49a
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/pom.xml
@@ -0,0 +1,66 @@
+
+
+ 4.0.0
+ com.baeldung.boot.persistence
+ spring-boot-persistence-3
+ 0.0.1-SNAPSHOT
+ spring-boot-persistence-3
+
+
+ com.baeldung
+ persistence-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+
+ org.junit
+ junit-bom
+ ${junit-jupiter.version}
+ pom
+ import
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring.boot.dependencies}
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+ 2.1.8.RELEASE
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/LargeResultSetApplication.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/LargeResultSetApplication.java
new file mode 100644
index 0000000000..d592894226
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/LargeResultSetApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.largeresultset;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class LargeResultSetApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(LargeResultSetApplication.class, args);
+ }
+
+}
diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/Student.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/Student.java
new file mode 100644
index 0000000000..283d0f032d
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/Student.java
@@ -0,0 +1,53 @@
+package com.baeldung.largeresultset;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class Student {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ private String firstName;
+ private String lastName;
+
+ public Student() {
+ }
+
+ public Student(String firstName, String lastName) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ @Override
+ public String toString() {
+ return "Student{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + '}';
+ }
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/StudentRepository.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/StudentRepository.java
new file mode 100644
index 0000000000..bc3815fa84
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/StudentRepository.java
@@ -0,0 +1,16 @@
+package com.baeldung.largeresultset;
+
+import java.util.stream.Stream;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Slice;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface StudentRepository extends JpaRepository {
+ Slice findAllByFirstName(String firstName, Pageable page);
+ Page findAllByLastName(String firstName, Pageable page);
+ Stream findAllByFirstName(String firstName);
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/service/EmailService.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/service/EmailService.java
new file mode 100644
index 0000000000..59169f66da
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/service/EmailService.java
@@ -0,0 +1,14 @@
+package com.baeldung.largeresultset.service;
+
+import org.springframework.stereotype.Service;
+
+import com.baeldung.largeresultset.Student;
+
+@Service
+public class EmailService {
+
+ public void sendEmailToStudent(Student student) {
+ System.out.println("sending email to: " + student);
+ }
+
+}
diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/service/StudentService.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/service/StudentService.java
new file mode 100644
index 0000000000..e65fc34849
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/largeresultset/service/StudentService.java
@@ -0,0 +1,62 @@
+package com.baeldung.largeresultset.service;
+
+import java.util.List;
+import java.util.stream.Stream;
+
+import javax.persistence.EntityManager;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Slice;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baeldung.largeresultset.Student;
+import com.baeldung.largeresultset.StudentRepository;
+
+@Service
+public class StudentService {
+ private static final int BATCH_SIZE = 5;
+ private final StudentRepository repository;
+ private final EmailService emailService;
+ private final EntityManager entityManager;
+
+ public StudentService(StudentRepository repository, EmailService emailService, EntityManager entityManager) {
+ this.repository = repository;
+ this.emailService = emailService;
+ this.entityManager = entityManager;
+ }
+
+ public void processStudentsByFirstName(String firstName) {
+ Slice slice = repository.findAllByFirstName(firstName, PageRequest.of(0, BATCH_SIZE));
+ List studentsInBatch = slice.getContent();
+ studentsInBatch.forEach(emailService::sendEmailToStudent);
+
+ while (slice.hasNext()) {
+ slice = repository.findAllByFirstName(firstName, slice.nextPageable());
+ slice.getContent()
+ .forEach(emailService::sendEmailToStudent);
+ }
+ }
+
+ public void processStudentsByLastName(String lastName) {
+ Page page = repository.findAllByLastName(lastName, PageRequest.of(0, BATCH_SIZE));
+ page.getContent()
+ .forEach(emailService::sendEmailToStudent);
+
+ while (page.hasNext()) {
+ page = repository.findAllByLastName(lastName, page.nextPageable());
+ page.getContent()
+ .forEach(emailService::sendEmailToStudent);
+ }
+ }
+
+ @Transactional(readOnly = true)
+ public void processStudentsByFirstNameUsingStreams(String firstName) {
+ try (Stream students = repository.findAllByFirstName(firstName)) {
+ students.peek(entityManager::detach)
+ .forEach(emailService::sendEmailToStudent);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-3/src/main/resources/application.yml b/persistence-modules/spring-boot-persistence-3/src/main/resources/application.yml
new file mode 100644
index 0000000000..bb9e377c34
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/src/main/resources/application.yml
@@ -0,0 +1,4 @@
+
+logging.level.org.hibernate:
+ SQL: DEBUG
+ type.descriptor.sql.BasicBinder: TRACE
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/largeresultset/LargeResultSetUnitTest.java b/persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/largeresultset/LargeResultSetUnitTest.java
new file mode 100644
index 0000000000..95e1231707
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/largeresultset/LargeResultSetUnitTest.java
@@ -0,0 +1,75 @@
+package com.baeldung.boot.largeresultset;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+
+import com.baeldung.largeresultset.LargeResultSetApplication;
+import com.baeldung.largeresultset.Student;
+import com.baeldung.largeresultset.StudentRepository;
+import com.baeldung.largeresultset.service.EmailService;
+import com.baeldung.largeresultset.service.StudentService;
+
+@SpringBootTest(classes = LargeResultSetApplication.class)
+class LargeResultSetUnitTest {
+
+ @Autowired
+ private StudentRepository repository;
+
+ @Autowired
+ private StudentService studentService;
+
+ @MockBean
+ private EmailService mockEmailService;
+
+ @AfterEach
+ public void afterEach() {
+ repository.deleteAll();
+ }
+
+ @Test
+ void givenTwelveRowsMatchingCriteria_whenRetrievingDataSliceBySlice_allDataIsProcessed() {
+ saveStudents(12);
+
+ studentService.processStudentsByFirstName("john");
+
+ verify(mockEmailService, times(12)).sendEmailToStudent(any());
+ }
+
+ @Test
+ void givenTwelveRowsMatchingCriteria_whenRetrievingDataPageByPage_allDataIsProcessed() {
+ saveStudents(12);
+
+ studentService.processStudentsByLastName("doe");
+
+ verify(mockEmailService, times(12)).sendEmailToStudent(any());
+ }
+
+ @Test
+ void processStudentsByFirstNameUsingStreams() {
+ saveStudents(12);
+
+ studentService.processStudentsByFirstNameUsingStreams("john");
+
+ verify(mockEmailService, times(12)).sendEmailToStudent(any());
+ }
+
+ private void saveStudents(int count) {
+ List students = IntStream.range(0, count)
+ .boxed()
+ .map(i -> new Student("john", "doe"))
+ .collect(Collectors.toList());
+ repository.saveAll(students);
+ }
+
+}
\ No newline at end of file