diff --git a/persistence-modules/spring-data-jpa-3/pom.xml b/persistence-modules/spring-data-jpa-3/pom.xml
index f743fce2a3..32f81d5745 100644
--- a/persistence-modules/spring-data-jpa-3/pom.xml
+++ b/persistence-modules/spring-data-jpa-3/pom.xml
@@ -18,29 +18,22 @@
+
+ org.springframework.boot
+ spring-boot-starter-web
+
org.springframework.boot
spring-boot-starter-data-jpa
- org.postgresql
- postgresql
- ${postgresql.version}
+ com.h2database
+ h2
+ runtime
+ ${h2.version}
-
- org.testcontainers
- junit-jupiter
- ${testcontainers.version}
- test
-
-
- org.testcontainers
- postgresql
- ${testcontainers.version}
- test
-
org.springframework.boot
spring-boot-starter-test
@@ -71,8 +64,7 @@
- 1.12.2
- 42.2.8
+ 1.4.200
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/tx/Payment.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/Payment.java
similarity index 97%
rename from persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/tx/Payment.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/Payment.java
index 37f3d09381..2c24e5777e 100644
--- a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/tx/Payment.java
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/Payment.java
@@ -1,4 +1,4 @@
-package com.baeldung.tx;
+package com.baeldung.model;
import javax.persistence.*;
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/User.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/User.java
new file mode 100644
index 0000000000..94d0c023f2
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/User.java
@@ -0,0 +1,42 @@
+package com.baeldung.model;
+
+import javax.persistence.*;
+import java.util.Set;
+
+@Entity
+@Table(name = "users")
+public class User {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ private String username;
+
+ @ElementCollection
+ private Set permissions;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public Set getPermissions() {
+ return permissions;
+ }
+
+ public void setPermissions(Set permissions) {
+ this.permissions = permissions;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/repository/UserRepository.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/repository/UserRepository.java
new file mode 100644
index 0000000000..bb3ce781f6
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/repository/UserRepository.java
@@ -0,0 +1,17 @@
+package com.baeldung.repository;
+
+import com.baeldung.model.User;
+import org.springframework.data.jpa.repository.EntityGraph;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface UserRepository extends JpaRepository {
+
+ @EntityGraph(attributePaths = "permissions")
+ Optional findDetailedByUsername(String username);
+
+ Optional findSummaryByUsername(String username);
+
+ Optional findByUsername(String username);
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/SimpleUserService.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/SimpleUserService.java
new file mode 100644
index 0000000000..6782254f61
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/SimpleUserService.java
@@ -0,0 +1,24 @@
+package com.baeldung.service;
+
+import com.baeldung.model.User;
+import com.baeldung.repository.UserRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Optional;
+
+@Service
+public class SimpleUserService implements UserService {
+
+ private final UserRepository userRepository;
+
+ public SimpleUserService(UserRepository userRepository) {
+ this.userRepository = userRepository;
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public Optional findOne(String username) {
+ return userRepository.findDetailedByUsername(username);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/UserService.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/UserService.java
new file mode 100644
index 0000000000..11b3dc82ce
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/service/UserService.java
@@ -0,0 +1,9 @@
+package com.baeldung.service;
+
+import com.baeldung.model.User;
+
+import java.util.Optional;
+
+public interface UserService {
+ Optional findOne(String username);
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/DetailedUserDto.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/DetailedUserDto.java
new file mode 100644
index 0000000000..0d8fe02b91
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/DetailedUserDto.java
@@ -0,0 +1,45 @@
+package com.baeldung.web;
+
+import com.baeldung.model.User;
+
+import java.util.Set;
+
+public class DetailedUserDto {
+
+ private Long id;
+ private String username;
+ private Set permissions;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public Set getPermissions() {
+ return permissions;
+ }
+
+ public void setPermissions(Set permissions) {
+ this.permissions = permissions;
+ }
+
+ public static DetailedUserDto fromEntity(User user) {
+ DetailedUserDto detailed = new DetailedUserDto();
+ detailed.setId(user.getId());
+ detailed.setUsername(user.getUsername());
+ detailed.setPermissions(user.getPermissions());
+
+ return detailed;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/UserController.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/UserController.java
new file mode 100644
index 0000000000..867d60cc2f
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/web/UserController.java
@@ -0,0 +1,27 @@
+package com.baeldung.web;
+
+import com.baeldung.service.UserService;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/users")
+public class UserController {
+
+ private final UserService userService;
+
+ public UserController(UserService userService) {
+ this.userService = userService;
+ }
+
+ @GetMapping("/{username}")
+ public ResponseEntity> findOne(@PathVariable String username) {
+ return userService.findOne(username)
+ .map(DetailedUserDto::fromEntity)
+ .map(ResponseEntity::ok)
+ .orElse(ResponseEntity.notFound().build());
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/osiv/UserControllerIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/osiv/UserControllerIntegrationTest.java
new file mode 100644
index 0000000000..ba94fc111b
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/osiv/UserControllerIntegrationTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.osiv;
+
+import com.baeldung.model.User;
+import com.baeldung.repository.UserRepository;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.web.servlet.MockMvc;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+@ActiveProfiles("test")
+class UserControllerIntegrationTest {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ void setUp() {
+ User user = new User();
+ user.setUsername("root");
+ user.setPermissions(new HashSet<>(Arrays.asList("PERM_READ", "PERM_WRITE")));
+
+ userRepository.save(user);
+ }
+
+ @Test
+ void givenTheUserExists_WhenOsivIsEnabled_ThenLazyInitWorkEverywhere() throws Exception {
+ mockMvc.perform(get("/users/root"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.username").value("root"))
+ .andExpect(jsonPath("$.permissions", containsInAnyOrder("PERM_READ", "PERM_WRITE")));
+ }
+
+ @AfterEach
+ void flushDb() {
+ userRepository.deleteAll();
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/tx/ManualTransactionIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/tx/ManualTransactionIntegrationTest.java
index 62d64d4372..1ce8e91ec5 100644
--- a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/tx/ManualTransactionIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/tx/ManualTransactionIntegrationTest.java
@@ -1,10 +1,10 @@
package com.baeldung.tx;
+import com.baeldung.model.Payment;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.PlatformTransactionManager;
@@ -14,27 +14,17 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
-import org.testcontainers.containers.PostgreSQLContainer;
-import org.testcontainers.junit.jupiter.Container;
-import org.testcontainers.junit.jupiter.Testcontainers;
import javax.persistence.EntityManager;
-import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace.NONE;
import static org.springframework.transaction.annotation.Propagation.NOT_SUPPORTED;
@DataJpaTest
-@Testcontainers
@ActiveProfiles("test")
-@AutoConfigureTestDatabase(replace = NONE)
@Transactional(propagation = NOT_SUPPORTED)
class ManualTransactionIntegrationTest {
- @Container
- private static PostgreSQLContainer> pg = initPostgres();
-
@Autowired
private PlatformTransactionManager transactionManager;
@@ -159,13 +149,4 @@ class ManualTransactionIntegrationTest {
.getResultList()).hasSize(1);
}
- private static PostgreSQLContainer> initPostgres() {
- PostgreSQLContainer> pg = new PostgreSQLContainer<>("postgres:11.1")
- .withDatabaseName("baeldung")
- .withUsername("test")
- .withPassword("test");
- pg.setPortBindings(singletonList("54320:5432"));
-
- return pg;
- }
}
diff --git a/persistence-modules/spring-data-jpa-3/src/test/resources/application-test.properties b/persistence-modules/spring-data-jpa-3/src/test/resources/application-test.properties
index aa7093f751..f9497c8f37 100644
--- a/persistence-modules/spring-data-jpa-3/src/test/resources/application-test.properties
+++ b/persistence-modules/spring-data-jpa-3/src/test/resources/application-test.properties
@@ -1,4 +1,2 @@
spring.jpa.hibernate.ddl-auto=update
-spring.datasource.url=jdbc:postgresql://localhost:54320/baeldung
-spring.datasource.username=test
-spring.datasource.password=test
+spring.datasource.url=jdbc:h2:mem:jpa3
\ No newline at end of file