diff --git a/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimeUtilsUnitTest.java b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimeUtilsUnitTest.java
index 6b49558f1b..e13c53bfbb 100644
--- a/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimeUtilsUnitTest.java
+++ b/core-java-modules/core-java-date-operations/src/test/java/com/baeldung/datetime/sql/TimeUtilsUnitTest.java
@@ -7,15 +7,9 @@ import org.junit.Test;
import com.baeldung.datetime.sql.TimeUtils;
import java.text.ParseException;
-import java.util.Date;
public class TimeUtilsUnitTest {
- @Test
- public void givenCurrentTime_thenNowIsReturned() {
- assertEquals(TimeUtils.getNow(), new Date());
- }
-
@Test(expected = IllegalArgumentException.class)
public void givenTimeAsString_whenPatternIsNotRespected_thenExceptionIsThrown() {
TimeUtils.getTime("10 11 12");
diff --git a/persistence-modules/jnosql/pom.xml b/persistence-modules/jnosql/pom.xml
index 91ceddaadd..8773456285 100644
--- a/persistence-modules/jnosql/pom.xml
+++ b/persistence-modules/jnosql/pom.xml
@@ -17,8 +17,8 @@
- jnosql-diana
jnosql-artemis
+ jnosql-diana
diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml
index de20b135fa..ce1f0d2163 100644
--- a/persistence-modules/pom.xml
+++ b/persistence-modules/pom.xml
@@ -18,28 +18,34 @@
apache-cayenne
core-java-persistence
deltaspike
+ elasticsearch
flyway
hbase
hibernate5
- hibernate-ogm
- hibernate-mapping
hibernate5-2
+ hibernate-mapping
+ hibernate-ogm
influxdb
java-cassandra
java-cockroachdb
java-jdbi
- java-jpa
- java-jpa-2
- java-mongodb
- persistence-libraries
- jnosql
+ java-jpa
+ java-jpa-2
+ java-mongodb
+ jnosql
+ jpa-hibernate-cascade-type
liquibase
orientdb
+ persistence-libraries
querydsl
+ r2dbc
redis
+
solr
- spring-boot-persistence-h2
+ spring-boot-jdbi
+ spring-boot-mysql
spring-boot-persistence
+ spring-boot-persistence-h2
spring-boot-persistence-mongodb
spring-data-cassandra
spring-data-cassandra-reactive
@@ -50,19 +56,20 @@
spring-data-gemfire
spring-data-geode
spring-data-jpa
+ spring-data-jpa-2
spring-data-jpa-3
+ spring-data-jpa-4
spring-data-keyvalue
- spring-data-mongodb
+ spring-data-mongodb
spring-data-neo4j
spring-data-redis
spring-data-solr
spring-hibernate-3
- spring-hibernate-5
+ spring-hibernate-5
spring-hibernate4
spring-jpa
+
spring-persistence-simple
- jpa-hibernate-cascade-type
- r2dbc
- spring-boot-jdbi
+
diff --git a/persistence-modules/spring-data-jpa-2/README.md b/persistence-modules/spring-data-jpa-2/README.md
index 1f7de81c02..d1875d91d4 100644
--- a/persistence-modules/spring-data-jpa-2/README.md
+++ b/persistence-modules/spring-data-jpa-2/README.md
@@ -9,7 +9,3 @@
- [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable)
- [Spring Data JPA Delete and Relationships](https://www.baeldung.com/spring-data-jpa-delete)
- [Spring Data JPA and Named Entity Graphs](https://www.baeldung.com/spring-data-jpa-named-entity-graphs)
-- [Batch Insert/Update with Hibernate/JPA](https://www.baeldung.com/jpa-hibernate-batch-insert-update)
-- [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush)
-- [Derived Query Methods in Spring Data JPA Repositories](https://www.baeldung.com/spring-data-derived-queries)
-- [LIKE Queries in Spring JPA Repositories](https://www.baeldung.com/spring-jpa-like-queries)
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/FruitRepository.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/FruitRepository.java
index 9f92909b66..5055252adf 100644
--- a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/FruitRepository.java
+++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/FruitRepository.java
@@ -23,5 +23,5 @@ public interface FruitRepository extends JpaRepository {
@Modifying
@Query("delete from Fruit f where f.name=:name or f.color=:color")
- List deleteFruits(@Param("name") String name, @Param("color") String color);
+ int deleteFruits(@Param("name") String name, @Param("color") String color);
}
diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorIntegrationTest.java
similarity index 92%
rename from persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorTest.java
rename to persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorIntegrationTest.java
index 29ef52dcef..4d3661e717 100644
--- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorTest.java
+++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitPopulatorIntegrationTest.java
@@ -14,7 +14,7 @@ import com.baeldung.entity.Fruit;
@RunWith(SpringRunner.class)
@SpringBootTest
-public class FruitPopulatorTest {
+public class FruitPopulatorIntegrationTest {
@Autowired
private FruitRepository fruitRepository;
diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitRepositoryIntegrationTest.java
index 866cf1157b..cf771dc833 100644
--- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/FruitRepositoryIntegrationTest.java
@@ -1,7 +1,6 @@
package com.baeldung.repository;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
import java.util.List;
@@ -69,9 +68,8 @@ class FruitRepositoryIntegrationTest {
@Sql(scripts = { "/test-fruit-data.sql" })
public void givenFruits_WhenDeletedByColorOrName_ThenDeletedFruitsShouldReturn() {
- List fruits = fruitRepository.deleteFruits("apple", "green");
+ int deletedCount = fruitRepository.deleteFruits("apple", "green");
- assertEquals("number of fruits are not matching", 3, fruits.size());
- fruits.forEach(fruit -> assertTrue("Its not a green fruit or apple", ("green".equals(fruit.getColor())) || "apple".equals(fruit.getColor())));
+ assertEquals("number of fruits are not matching", 3, deletedCount);
}
}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/SongRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/SongRepositoryIntegrationTest.java
index c3d0636881..14912a4ecb 100644
--- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/SongRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/SongRepositoryIntegrationTest.java
@@ -1,7 +1,10 @@
package com.baeldung.repository;
-import com.baeldung.entity.Song;
-import org.junit.jupiter.api.Test;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -9,9 +12,7 @@ import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
+import com.baeldung.entity.Song;
@RunWith(SpringRunner.class)
@SpringBootTest
diff --git a/persistence-modules/spring-data-jpa-2/src/test/resources/test-fruit-data.sql b/persistence-modules/spring-data-jpa-2/src/test/resources/test-fruit-data.sql
index ce2189121f..d99f42e5a7 100644
--- a/persistence-modules/spring-data-jpa-2/src/test/resources/test-fruit-data.sql
+++ b/persistence-modules/spring-data-jpa-2/src/test/resources/test-fruit-data.sql
@@ -1,4 +1,6 @@
-insert into fruit(id,name,color) values (1,'apple','red');
-insert into fruit(id,name,color) values (2,'custard apple','green');
-insert into fruit(id,name,color) values (3,'mango','yellow');
+truncate table fruit;
+
+insert into fruit(id,name,color) values (1,'apple','red');
+insert into fruit(id,name,color) values (2,'custard apple','green');
+insert into fruit(id,name,color) values (3,'mango','yellow');
insert into fruit(id,name,color) values (4,'guava','green');
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-3/README.md b/persistence-modules/spring-data-jpa-3/README.md
index 28e62a9de1..a86c1e5ec2 100644
--- a/persistence-modules/spring-data-jpa-3/README.md
+++ b/persistence-modules/spring-data-jpa-3/README.md
@@ -1,3 +1,21 @@
-### Relevant Articles:
+### Relevant Articles:
+- [Limiting Query Results with JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results)
+- [Sorting Query Results with Spring Data](https://www.baeldung.com/spring-data-sorting)
+- [INSERT Statement in JPA](https://www.baeldung.com/jpa-insert)
+- [Pagination and Sorting using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-pagination-sorting)
+- [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example)
+- [DB Integration Tests with Spring Boot and Testcontainers](https://www.baeldung.com/spring-boot-testcontainers-integration-test)
+- [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation)
+- [Spring Data JPA Batch Inserts](https://www.baeldung.com/spring-data-jpa-batch-inserts)
+- [Batch Insert/Update with Hibernate/JPA](https://www.baeldung.com/jpa-hibernate-batch-insert-update)
+- [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush)
- [Programmatic Transaction Management in Spring](https://www.baeldung.com/spring-programmatic-transaction-management)
+### Eclipse Config
+After importing the project into Eclipse, you may see the following error:
+"No persistence xml file found in project"
+
+This can be ignored:
+- Project -> Properties -> Java Persistance -> JPA -> Error/Warnings -> Select Ignore on "No persistence xml file found in project"
+Or:
+- Eclipse -> Preferences - Validation - disable the "Build" execution of the JPA Validator
diff --git a/persistence-modules/spring-data-jpa-3/pom.xml b/persistence-modules/spring-data-jpa-3/pom.xml
index 32f81d5745..99df250a9a 100644
--- a/persistence-modules/spring-data-jpa-3/pom.xml
+++ b/persistence-modules/spring-data-jpa-3/pom.xml
@@ -26,6 +26,29 @@
org.springframework.boot
spring-boot-starter-data-jpa
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+ com.h2database
+ h2
+
+
+ net.ttddyy
+ datasource-proxy
+ ${datasource-proxy.version}
+
+
+ org.postgresql
+ postgresql
+ ${postgresql.version}
+
com.h2database
h2
@@ -61,10 +84,23 @@
${junit-platform.version}
test
+
+
+
+ org.testcontainers
+ postgresql
+ ${testcontainers.version}
+ test
+
+
+ 1.4.1
+ 21.0
+ 1.12.2
+ 42.2.8
+ 1.12.2
1.4.200
-
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/batchinserts/DatasourceProxyBeanPostProcessor.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/batchinserts/DatasourceProxyBeanPostProcessor.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/batchinserts/DatasourceProxyBeanPostProcessor.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/batchinserts/DatasourceProxyBeanPostProcessor.java
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/batchinserts/model/School.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/batchinserts/model/School.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/batchinserts/model/School.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/batchinserts/model/School.java
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/batchinserts/model/Student.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/batchinserts/model/Student.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/batchinserts/model/Student.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/batchinserts/model/Student.java
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/Application.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/Application.java
new file mode 100644
index 0000000000..aaca760499
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/Application.java
@@ -0,0 +1,17 @@
+package com.baeldung.boot;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication
+@EnableJpaRepositories("com.baeldung")
+@EntityScan("com.baeldung")
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/impl/PersonInsertRepository.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/impl/PersonInsertRepository.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/impl/PersonInsertRepository.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/impl/PersonInsertRepository.java
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/user/UserRepository.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/user/UserRepository.java
new file mode 100644
index 0000000000..53f692ff28
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/user/UserRepository.java
@@ -0,0 +1,99 @@
+package com.baeldung.boot.daos.user;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import com.baeldung.boot.domain.User;
+
+import java.time.LocalDate;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Stream;
+
+public interface UserRepository extends JpaRepository , UserRepositoryCustom{
+
+ Stream findAllByName(String name);
+
+ @Query("SELECT u FROM User u WHERE u.status = 1")
+ Collection findAllActiveUsers();
+
+ @Query("select u from User u where u.email like '%@gmail.com'")
+ List findUsersWithGmailAddress();
+
+ @Query(value = "SELECT * FROM Users u WHERE u.status = 1", nativeQuery = true)
+ Collection findAllActiveUsersNative();
+
+ @Query("SELECT u FROM User u WHERE u.status = ?1")
+ User findUserByStatus(Integer status);
+
+ @Query(value = "SELECT * FROM Users u WHERE u.status = ?1", nativeQuery = true)
+ User findUserByStatusNative(Integer status);
+
+ @Query("SELECT u FROM User u WHERE u.status = ?1 and u.name = ?2")
+ User findUserByStatusAndName(Integer status, String name);
+
+ @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name")
+ User findUserByStatusAndNameNamedParams(@Param("status") Integer status, @Param("name") String name);
+
+ @Query(value = "SELECT * FROM Users u WHERE u.status = :status AND u.name = :name", nativeQuery = true)
+ User findUserByStatusAndNameNamedParamsNative(@Param("status") Integer status, @Param("name") String name);
+
+ @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name")
+ User findUserByUserStatusAndUserName(@Param("status") Integer userStatus, @Param("name") String userName);
+
+ @Query("SELECT u FROM User u WHERE u.name like ?1%")
+ User findUserByNameLike(String name);
+
+ @Query("SELECT u FROM User u WHERE u.name like :name%")
+ User findUserByNameLikeNamedParam(@Param("name") String name);
+
+ @Query(value = "SELECT * FROM users u WHERE u.name LIKE ?1%", nativeQuery = true)
+ User findUserByNameLikeNative(String name);
+
+ @Query(value = "SELECT u FROM User u")
+ List findAllUsers(Sort sort);
+
+ @Query(value = "SELECT u FROM User u ORDER BY id")
+ Page findAllUsersWithPagination(Pageable pageable);
+
+ @Query(value = "SELECT * FROM Users ORDER BY id", countQuery = "SELECT count(*) FROM Users", nativeQuery = true)
+ Page findAllUsersWithPaginationNative(Pageable pageable);
+
+ @Modifying
+ @Query("update User u set u.status = :status where u.name = :name")
+ int updateUserSetStatusForName(@Param("status") Integer status, @Param("name") String name);
+
+ @Modifying
+ @Query(value = "UPDATE Users u SET u.status = ? WHERE u.name = ?", nativeQuery = true)
+ int updateUserSetStatusForNameNative(Integer status, String name);
+
+ @Query(value = "INSERT INTO Users (name, age, email, status, active) VALUES (:name, :age, :email, :status, :active)", nativeQuery = true)
+ @Modifying
+ void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("email") String email, @Param("status") Integer status, @Param("active") boolean active);
+
+ @Modifying
+ @Query(value = "UPDATE Users u SET status = ? WHERE u.name = ?", nativeQuery = true)
+ int updateUserSetStatusForNameNativePostgres(Integer status, String name);
+
+ @Query(value = "SELECT u FROM User u WHERE u.name IN :names")
+ List findUserByNameList(@Param("names") Collection names);
+
+ void deleteAllByCreationDateAfter(LocalDate date);
+
+ @Modifying(clearAutomatically = true, flushAutomatically = true)
+ @Query("update User u set u.active = false where u.lastLoginDate < :date")
+ void deactivateUsersNotLoggedInSince(@Param("date") LocalDate date);
+
+ @Modifying(clearAutomatically = true, flushAutomatically = true)
+ @Query("delete User u where u.active = false")
+ int deleteDeactivatedUsers();
+
+ @Modifying(clearAutomatically = true, flushAutomatically = true)
+ @Query(value = "alter table USERS add column deleted int(1) not null default 0", nativeQuery = true)
+ void addDeletedColumn();
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/user/UserRepositoryCustom.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/user/UserRepositoryCustom.java
new file mode 100644
index 0000000000..c586b54027
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/user/UserRepositoryCustom.java
@@ -0,0 +1,14 @@
+package com.baeldung.boot.daos.user;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
+
+import com.baeldung.boot.domain.User;
+
+public interface UserRepositoryCustom {
+ List findUserByEmails(Set emails);
+
+ List findAllUsersByPredicates(Collection> predicates);
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/user/UserRepositoryCustomImpl.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/user/UserRepositoryCustomImpl.java
new file mode 100644
index 0000000000..63a743b6b5
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/daos/user/UserRepositoryCustomImpl.java
@@ -0,0 +1,57 @@
+package com.baeldung.boot.daos.user;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Path;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import com.baeldung.boot.domain.User;
+
+public class UserRepositoryCustomImpl implements UserRepositoryCustom {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ @Override
+ public List findUserByEmails(Set emails) {
+ CriteriaBuilder cb = entityManager.getCriteriaBuilder();
+ CriteriaQuery query = cb.createQuery(User.class);
+ Root user = query.from(User.class);
+
+ Path emailPath = user.get("email");
+
+ List predicates = new ArrayList<>();
+ for (String email : emails) {
+
+ predicates.add(cb.like(emailPath, email));
+
+ }
+ query.select(user)
+ .where(cb.or(predicates.toArray(new Predicate[predicates.size()])));
+
+ return entityManager.createQuery(query)
+ .getResultList();
+ }
+
+ @Override
+ public List findAllUsersByPredicates(Collection> predicates) {
+ List allUsers = entityManager.createQuery("select u from User u", User.class).getResultList();
+ Stream allUsersStream = allUsers.stream();
+ for (java.util.function.Predicate predicate : predicates) {
+ allUsersStream = allUsersStream.filter(predicate);
+ }
+
+ return allUsersStream.collect(Collectors.toList());
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/domain/Customer.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/Customer.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/domain/Customer.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/Customer.java
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/domain/Person.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/Person.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/domain/Person.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/Person.java
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/Possession.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/Possession.java
new file mode 100644
index 0000000000..f13491ad82
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/Possession.java
@@ -0,0 +1,83 @@
+package com.baeldung.boot.domain;
+
+import javax.persistence.*;
+import com.baeldung.boot.domain.Possession;
+
+@Entity
+@Table
+public class Possession {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private long id;
+
+ private String name;
+
+ public Possession() {
+ super();
+ }
+
+ public Possession(final String name) {
+ super();
+
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = (prime * result) + (int) (id ^ (id >>> 32));
+ result = (prime * result) + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Possession other = (Possession) obj;
+ if (id != other.id) {
+ return false;
+ }
+ if (name == null) {
+ if (other.name != null) {
+ return false;
+ }
+ } else if (!name.equals(other.name)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Possesion [id=").append(id).append(", name=").append(name).append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/User.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/User.java
new file mode 100644
index 0000000000..cca00e52a2
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/domain/User.java
@@ -0,0 +1,132 @@
+package com.baeldung.boot.domain;
+
+import javax.persistence.*;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Objects;
+
+@Entity
+@Table(name = "users")
+public class User {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private int id;
+ private String name;
+ private LocalDate creationDate;
+ private LocalDate lastLoginDate;
+ private boolean active;
+ private int age;
+ @Column(unique = true, nullable = false)
+ private String email;
+ private Integer status;
+ @OneToMany
+ List possessionList;
+
+ public User() {
+ super();
+ }
+
+ public User(String name, LocalDate creationDate,String email, Integer status) {
+ this.name = name;
+ this.creationDate = creationDate;
+ this.email = email;
+ this.status = status;
+ this.active = true;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(final String email) {
+ this.email = email;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(final int age) {
+ this.age = age;
+ }
+
+ public LocalDate getCreationDate() {
+ return creationDate;
+ }
+
+ public List getPossessionList() {
+ return possessionList;
+ }
+
+ public void setPossessionList(List possessionList) {
+ this.possessionList = possessionList;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("User [name=").append(name).append(", id=").append(id).append("]");
+ return builder.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ User user = (User) o;
+ return id == user.id &&
+ age == user.age &&
+ Objects.equals(name, user.name) &&
+ Objects.equals(creationDate, user.creationDate) &&
+ Objects.equals(email, user.email) &&
+ Objects.equals(status, user.status);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, creationDate, age, email, status);
+ }
+
+ public LocalDate getLastLoginDate() {
+ return lastLoginDate;
+ }
+
+ public void setLastLoginDate(LocalDate lastLoginDate) {
+ this.lastLoginDate = lastLoginDate;
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public void setActive(boolean active) {
+ this.active = active;
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/passenger/CustomPassengerRepository.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/passenger/CustomPassengerRepository.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/passenger/CustomPassengerRepository.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/passenger/CustomPassengerRepository.java
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/passenger/Passenger.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/passenger/Passenger.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/passenger/Passenger.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/passenger/Passenger.java
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java
similarity index 98%
rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java
index cdb8cc98fb..14d5403cb5 100644
--- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java
@@ -1,10 +1,10 @@
package com.baeldung.boot.passenger;
+import java.util.List;
+
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
-import java.util.List;
-
interface PassengerRepository extends JpaRepository, CustomPassengerRepository {
Passenger findFirstByOrderBySeatNumberAsc();
@@ -12,11 +12,11 @@ interface PassengerRepository extends JpaRepository, CustomPass
Passenger findTopByOrderBySeatNumberAsc();
List findByOrderBySeatNumberAsc();
-
- List findByLastNameOrderBySeatNumberAsc(String lastName);
-
- List findByLastName(String lastName, Sort sort);
List findByFirstNameIgnoreCase(String firstName);
+ List findByLastNameOrderBySeatNumberAsc(String lastName);
+
+ List findByLastName(String lastName, Sort sort);
+
}
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Employee.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/entity/Employee.java
similarity index 93%
rename from persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Employee.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/entity/Employee.java
index 135439863f..4c3dbd25b7 100644
--- a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/entity/Employee.java
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/entity/Employee.java
@@ -1,36 +1,36 @@
-package com.baeldung.entity;
-
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-@Entity
-public class Employee {
-
- @Id
- private Long id;
- private String name;
-
- public Employee() {
- }
-
- public Employee(Long id, String name) {
- this.id = id;
- this.name = name;
- }
-
- 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;
- }
-}
+package com.baeldung.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class Employee {
+
+ @Id
+ private Long id;
+ private String name;
+
+ public Employee() {
+ }
+
+ public Employee(Long id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ 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;
+ }
+}
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/BasicUser.java
similarity index 96%
rename from persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/User.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/model/BasicUser.java
index 94d0c023f2..2dc9c18cf6 100644
--- 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/BasicUser.java
@@ -5,7 +5,7 @@ import java.util.Set;
@Entity
@Table(name = "users")
-public class User {
+public class BasicUser {
@Id
@GeneratedValue
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java
new file mode 100644
index 0000000000..3b9aa2cc18
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/MultipleDbApplication.java
@@ -0,0 +1,14 @@
+package com.baeldung.multipledb;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class MultipleDbApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MultipleDbApplication.class, args);
+ }
+
+}
+
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java
new file mode 100644
index 0000000000..bcf2cd84eb
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java
@@ -0,0 +1,68 @@
+package com.baeldung.multipledb;
+
+import com.google.common.base.Preconditions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+
+import javax.sql.DataSource;
+import java.util.HashMap;
+
+@Configuration
+@PropertySource({"classpath:persistence-multiple-db.properties"})
+@EnableJpaRepositories(basePackages = "com.baeldung.multipledb.dao.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager")
+@Profile("!tc")
+public class PersistenceProductConfiguration {
+ @Autowired
+ private Environment env;
+
+ public PersistenceProductConfiguration() {
+ super();
+ }
+
+ //
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean productEntityManager() {
+ final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
+ em.setDataSource(productDataSource());
+ em.setPackagesToScan("com.baeldung.multipledb.model.product");
+
+ final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ em.setJpaVendorAdapter(vendorAdapter);
+ final HashMap properties = new HashMap();
+ properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
+ em.setJpaPropertyMap(properties);
+
+ return em;
+ }
+
+ @Bean
+ public DataSource productDataSource() {
+ final DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
+ dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("product.jdbc.url")));
+ dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
+ dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
+
+ return dataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager productTransactionManager() {
+ final JpaTransactionManager transactionManager = new JpaTransactionManager();
+ transactionManager.setEntityManagerFactory(productEntityManager().getObject());
+ return transactionManager;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/dao/product/ProductRepository.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/dao/product/ProductRepository.java
new file mode 100644
index 0000000000..022099eed0
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/dao/product/ProductRepository.java
@@ -0,0 +1,13 @@
+package com.baeldung.multipledb.dao.product;
+
+import java.util.List;
+
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import com.baeldung.multipledb.model.product.ProductMultipleDB;
+
+public interface ProductRepository extends PagingAndSortingRepository {
+
+ List findAllByPrice(double price, Pageable pageable);
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/model/product/ProductMultipleDB.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/model/product/ProductMultipleDB.java
new file mode 100644
index 0000000000..8bdff340ac
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/multipledb/model/product/ProductMultipleDB.java
@@ -0,0 +1,67 @@
+package com.baeldung.multipledb.model.product;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(schema = "products")
+public class ProductMultipleDB {
+
+ @Id
+ private int id;
+
+ private String name;
+
+ private double price;
+
+ public ProductMultipleDB() {
+ super();
+ }
+
+ private ProductMultipleDB(int id, String name, double price) {
+ super();
+ this.id = id;
+ this.name = name;
+ this.price = price;
+ }
+
+ public static ProductMultipleDB from(int id, String name, double price) {
+ return new ProductMultipleDB(id, name, price);
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public double getPrice() {
+ return price;
+ }
+
+ public void setPrice(final double price) {
+ this.price = price;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Product [name=")
+ .append(name)
+ .append(", id=")
+ .append(id)
+ .append("]");
+ return builder.toString();
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/EmployeeRepository.java b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/repository/EmployeeRepository.java
similarity index 95%
rename from persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/EmployeeRepository.java
rename to persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/repository/EmployeeRepository.java
index 2c4fee80e0..8f0a80814b 100644
--- a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/repository/EmployeeRepository.java
+++ b/persistence-modules/spring-data-jpa-3/src/main/java/com/baeldung/repository/EmployeeRepository.java
@@ -1,9 +1,9 @@
-package com.baeldung.repository;
-
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import com.baeldung.entity.Employee;
-
-public interface EmployeeRepository extends JpaRepository {
-
-}
+package com.baeldung.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.baeldung.entity.Employee;
+
+public interface EmployeeRepository extends JpaRepository {
+
+}
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
index bb3ce781f6..c656055751 100644
--- 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
@@ -1,17 +1,17 @@
package com.baeldung.repository;
-import com.baeldung.model.User;
+import com.baeldung.model.BasicUser;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
-public interface UserRepository extends JpaRepository {
+public interface UserRepository extends JpaRepository {
@EntityGraph(attributePaths = "permissions")
- Optional findDetailedByUsername(String username);
+ Optional findDetailedByUsername(String username);
- Optional findSummaryByUsername(String username);
+ Optional findSummaryByUsername(String username);
- Optional findByUsername(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
index 6782254f61..4bd1dc5e41 100644
--- 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
@@ -1,6 +1,6 @@
package com.baeldung.service;
-import com.baeldung.model.User;
+import com.baeldung.model.BasicUser;
import com.baeldung.repository.UserRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -18,7 +18,7 @@ public class SimpleUserService implements UserService {
@Override
@Transactional(readOnly = true)
- public Optional findOne(String username) {
+ 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
index 11b3dc82ce..34a07199b2 100644
--- 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
@@ -1,9 +1,9 @@
package com.baeldung.service;
-import com.baeldung.model.User;
+import com.baeldung.model.BasicUser;
import java.util.Optional;
public interface UserService {
- Optional findOne(String username);
+ 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
index 0d8fe02b91..95a4f6eb07 100644
--- 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
@@ -1,6 +1,6 @@
package com.baeldung.web;
-import com.baeldung.model.User;
+import com.baeldung.model.BasicUser;
import java.util.Set;
@@ -34,7 +34,7 @@ public class DetailedUserDto {
this.permissions = permissions;
}
- public static DetailedUserDto fromEntity(User user) {
+ public static DetailedUserDto fromEntity(BasicUser user) {
DetailedUserDto detailed = new DetailedUserDto();
detailed.setId(user.getId());
detailed.setUsername(user.getUsername());
diff --git a/persistence-modules/spring-data-jpa-3/src/main/resources/application.properties b/persistence-modules/spring-data-jpa-3/src/main/resources/application.properties
new file mode 100644
index 0000000000..f127dd5e50
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/resources/application.properties
@@ -0,0 +1,6 @@
+spring.main.allow-bean-definition-overriding=true
+
+spring.jpa.properties.hibernate.jdbc.batch_size=4
+spring.jpa.properties.hibernate.order_inserts=true
+spring.jpa.properties.hibernate.order_updates=true
+spring.jpa.properties.hibernate.generate_statistics=true
diff --git a/persistence-modules/spring-data-jpa-3/src/main/resources/logback.xml b/persistence-modules/spring-data-jpa-3/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-3/src/main/resources/persistence-multiple-db.properties b/persistence-modules/spring-data-jpa-3/src/main/resources/persistence-multiple-db.properties
new file mode 100644
index 0000000000..75534e8a54
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/main/resources/persistence-multiple-db.properties
@@ -0,0 +1,13 @@
+# jdbc.X
+jdbc.driverClassName=org.h2.Driver
+user.jdbc.url=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS
+product.jdbc.url=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS
+jdbc.user=sa
+jdbc.pass=sa
+
+# hibernate.X
+hibernate.dialect=org.hibernate.dialect.H2Dialect
+hibernate.show_sql=false
+hibernate.hbm2ddl.auto=create-drop
+hibernate.cache.use_second_level_cache=false
+hibernate.cache.use_query_cache=false
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/SpringContextIntegrationTest.java
new file mode 100644
index 0000000000..a986cc7e21
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/SpringContextIntegrationTest.java
@@ -0,0 +1,17 @@
+package com.baeldung;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.boot.Application;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Application.class)
+public class SpringContextIntegrationTest {
+
+ @Test
+ public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/SpringContextTest.java
new file mode 100644
index 0000000000..eaccf4acba
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/SpringContextTest.java
@@ -0,0 +1,17 @@
+package com.baeldung;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.boot.Application;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Application.class)
+public class SpringContextTest {
+
+ @Test
+ public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/SpringJpaContextIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/SpringJpaContextIntegrationTest.java
new file mode 100644
index 0000000000..27c71c5bcc
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/SpringJpaContextIntegrationTest.java
@@ -0,0 +1,19 @@
+package com.baeldung;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.boot.Application;
+
+@RunWith(SpringRunner.class)
+@DataJpaTest
+@ContextConfiguration(classes = Application.class)
+public class SpringJpaContextIntegrationTest {
+
+ @Test
+ public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+ }
+}
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/batchinserts/BatchInsertIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/BatchInsertIntegrationTest.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/test/java/com/baeldung/batchinserts/BatchInsertIntegrationTest.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/BatchInsertIntegrationTest.java
diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/batchinserts/JpaBatchInsertsIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/JpaBatchInsertsIntegrationTest.java
similarity index 97%
rename from persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/batchinserts/JpaBatchInsertsIntegrationTest.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/JpaBatchInsertsIntegrationTest.java
index 9e81dbc04d..311f227322 100644
--- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/batchinserts/JpaBatchInsertsIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/JpaBatchInsertsIntegrationTest.java
@@ -3,12 +3,12 @@ package com.baeldung.batchinserts;
import static com.baeldung.batchinserts.TestObjectHelper.createSchool;
import static com.baeldung.batchinserts.TestObjectHelper.createStudent;
-import com.baeldung.batchinserts.model.School;
-import com.baeldung.batchinserts.model.Student;
import java.util.List;
+
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
+
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -17,8 +17,12 @@ import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
+import com.baeldung.batchinserts.model.School;
+import com.baeldung.batchinserts.model.Student;
+import com.baeldung.boot.Application;
+
@RunWith(SpringRunner.class)
-@SpringBootTest
+@SpringBootTest(classes = Application.class)
@Transactional
@ActiveProfiles("batchinserts")
public class JpaBatchInsertsIntegrationTest {
diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/batchinserts/JpaNoBatchInsertsIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/JpaNoBatchInsertsIntegrationTest.java
similarity index 93%
rename from persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/batchinserts/JpaNoBatchInsertsIntegrationTest.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/JpaNoBatchInsertsIntegrationTest.java
index 20502c793d..75b3f1f3aa 100644
--- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/batchinserts/JpaNoBatchInsertsIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/JpaNoBatchInsertsIntegrationTest.java
@@ -3,6 +3,8 @@ package com.baeldung.batchinserts;
import static com.baeldung.batchinserts.TestObjectHelper.createSchool;
import com.baeldung.batchinserts.model.School;
+import com.baeldung.boot.Application;
+
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.junit.After;
@@ -15,7 +17,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringRunner.class)
-@SpringBootTest
+@SpringBootTest(classes = Application.class)
@Transactional
@ActiveProfiles("batchinserts")
@TestPropertySource(properties = "spring.jpa.properties.hibernate.jdbc.batch_size=-1")
diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/batchinserts/TestObjectHelper.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/TestObjectHelper.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/batchinserts/TestObjectHelper.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/batchinserts/TestObjectHelper.java
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/CustomerRepository.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/CustomerRepository.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/CustomerRepository.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/CustomerRepository.java
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/PersonInsertRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/PersonInsertRepositoryIntegrationTest.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/PersonInsertRepositoryIntegrationTest.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/PersonInsertRepositoryIntegrationTest.java
diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java
new file mode 100644
index 0000000000..17ee6a94ba
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java
@@ -0,0 +1,545 @@
+package com.baeldung.boot.daos;
+
+import org.junit.After;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.JpaSort;
+import org.springframework.data.mapping.PropertyReferenceException;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baeldung.boot.daos.user.UserRepository;
+import com.baeldung.boot.domain.User;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import java.time.LocalDate;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.*;
+
+public class UserRepositoryCommon {
+
+ final String USER_EMAIL = "email@example.com";
+ final String USER_EMAIL2 = "email2@example.com";
+ final String USER_EMAIL3 = "email3@example.com";
+ final String USER_EMAIL4 = "email4@example.com";
+ final Integer INACTIVE_STATUS = 0;
+ final Integer ACTIVE_STATUS = 1;
+ final String USER_EMAIL5 = "email5@example.com";
+ final String USER_EMAIL6 = "email6@example.com";
+ final String USER_NAME_ADAM = "Adam";
+ final String USER_NAME_PETER = "Peter";
+
+ @Autowired
+ protected UserRepository userRepository;
+ @Autowired
+ private EntityManager entityManager;
+
+ @Test
+ @Transactional
+ public void givenUsersWithSameNameInDB_WhenFindAllByName_ThenReturnStreamOfUsers() {
+ User user1 = new User();
+ user1.setName(USER_NAME_ADAM);
+ user1.setEmail(USER_EMAIL);
+ userRepository.save(user1);
+
+ User user2 = new User();
+ user2.setName(USER_NAME_ADAM);
+ user2.setEmail(USER_EMAIL2);
+ userRepository.save(user2);
+
+ User user3 = new User();
+ user3.setName(USER_NAME_ADAM);
+ user3.setEmail(USER_EMAIL3);
+ userRepository.save(user3);
+
+ User user4 = new User();
+ user4.setName("SAMPLE");
+ user4.setEmail(USER_EMAIL4);
+ userRepository.save(user4);
+
+ try (Stream foundUsersStream = userRepository.findAllByName(USER_NAME_ADAM)) {
+ assertThat(foundUsersStream.count()).isEqualTo(3l);
+ }
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindAllWithQueryAnnotation_ThenReturnCollectionWithActiveUsers() {
+ User user1 = new User();
+ user1.setName(USER_NAME_ADAM);
+ user1.setEmail(USER_EMAIL);
+ user1.setStatus(ACTIVE_STATUS);
+ userRepository.save(user1);
+
+ User user2 = new User();
+ user2.setName(USER_NAME_ADAM);
+ user2.setEmail(USER_EMAIL2);
+ user2.setStatus(ACTIVE_STATUS);
+ userRepository.save(user2);
+
+ User user3 = new User();
+ user3.setName(USER_NAME_ADAM);
+ user3.setEmail(USER_EMAIL3);
+ user3.setStatus(INACTIVE_STATUS);
+ userRepository.save(user3);
+
+ Collection allActiveUsers = userRepository.findAllActiveUsers();
+
+ assertThat(allActiveUsers.size()).isEqualTo(2);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindAllWithQueryAnnotationNative_ThenReturnCollectionWithActiveUsers() {
+ User user1 = new User();
+ user1.setName(USER_NAME_ADAM);
+ user1.setEmail(USER_EMAIL);
+ user1.setStatus(ACTIVE_STATUS);
+ userRepository.save(user1);
+
+ User user2 = new User();
+ user2.setName(USER_NAME_ADAM);
+ user2.setEmail(USER_EMAIL2);
+ user2.setStatus(ACTIVE_STATUS);
+ userRepository.save(user2);
+
+ User user3 = new User();
+ user3.setName(USER_NAME_ADAM);
+ user3.setEmail(USER_EMAIL3);
+ user3.setStatus(INACTIVE_STATUS);
+ userRepository.save(user3);
+
+ Collection allActiveUsers = userRepository.findAllActiveUsersNative();
+
+ assertThat(allActiveUsers.size()).isEqualTo(2);
+ }
+
+ @Test
+ public void givenUserInDB_WhenFindUserByStatusWithQueryAnnotation_ThenReturnActiveUser() {
+ User user = new User();
+ user.setName(USER_NAME_ADAM);
+ user.setEmail(USER_EMAIL);
+ user.setStatus(ACTIVE_STATUS);
+ userRepository.save(user);
+
+ User userByStatus = userRepository.findUserByStatus(ACTIVE_STATUS);
+
+ assertThat(userByStatus.getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUserInDB_WhenFindUserByStatusWithQueryAnnotationNative_ThenReturnActiveUser() {
+ User user = new User();
+ user.setName(USER_NAME_ADAM);
+ user.setEmail(USER_EMAIL);
+ user.setStatus(ACTIVE_STATUS);
+ userRepository.save(user);
+
+ User userByStatus = userRepository.findUserByStatusNative(ACTIVE_STATUS);
+
+ assertThat(userByStatus.getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindUserByStatusAndNameWithQueryAnnotationIndexedParams_ThenReturnOneUser() {
+ User user = new User();
+ user.setName(USER_NAME_ADAM);
+ user.setEmail(USER_EMAIL);
+ user.setStatus(ACTIVE_STATUS);
+ userRepository.save(user);
+
+ User user2 = new User();
+ user2.setName(USER_NAME_PETER);
+ user2.setEmail(USER_EMAIL2);
+ user2.setStatus(ACTIVE_STATUS);
+ userRepository.save(user2);
+
+ User userByStatus = userRepository.findUserByStatusAndName(ACTIVE_STATUS, USER_NAME_ADAM);
+
+ assertThat(userByStatus.getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindUserByStatusAndNameWithQueryAnnotationNamedParams_ThenReturnOneUser() {
+ User user = new User();
+ user.setName(USER_NAME_ADAM);
+ user.setEmail(USER_EMAIL);
+ user.setStatus(ACTIVE_STATUS);
+ userRepository.save(user);
+
+ User user2 = new User();
+ user2.setName(USER_NAME_PETER);
+ user2.setEmail(USER_EMAIL2);
+ user2.setStatus(ACTIVE_STATUS);
+ userRepository.save(user2);
+
+ User userByStatus = userRepository.findUserByStatusAndNameNamedParams(ACTIVE_STATUS, USER_NAME_ADAM);
+
+ assertThat(userByStatus.getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindUserByStatusAndNameWithQueryAnnotationNativeNamedParams_ThenReturnOneUser() {
+ User user = new User();
+ user.setName(USER_NAME_ADAM);
+ user.setEmail(USER_EMAIL);
+ user.setStatus(ACTIVE_STATUS);
+ userRepository.save(user);
+
+ User user2 = new User();
+ user2.setName(USER_NAME_PETER);
+ user2.setEmail(USER_EMAIL2);
+ user2.setStatus(ACTIVE_STATUS);
+ userRepository.save(user2);
+
+ User userByStatus = userRepository.findUserByStatusAndNameNamedParamsNative(ACTIVE_STATUS, USER_NAME_ADAM);
+
+ assertThat(userByStatus.getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindUserByStatusAndNameWithQueryAnnotationNamedParamsCustomNames_ThenReturnOneUser() {
+ User user = new User();
+ user.setName(USER_NAME_ADAM);
+ user.setEmail(USER_EMAIL);
+ user.setStatus(ACTIVE_STATUS);
+ userRepository.save(user);
+
+ User user2 = new User();
+ user2.setName(USER_NAME_PETER);
+ user2.setEmail(USER_EMAIL2);
+ user2.setStatus(ACTIVE_STATUS);
+ userRepository.save(user2);
+
+ User userByStatus = userRepository.findUserByUserStatusAndUserName(ACTIVE_STATUS, USER_NAME_ADAM);
+
+ assertThat(userByStatus.getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindUserByNameLikeWithQueryAnnotationIndexedParams_ThenReturnUser() {
+ User user = new User();
+ user.setName(USER_NAME_ADAM);
+ user.setEmail(USER_EMAIL);
+ user.setStatus(ACTIVE_STATUS);
+ userRepository.save(user);
+
+ User userByStatus = userRepository.findUserByNameLike("Ad");
+
+ assertThat(userByStatus.getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindUserByNameLikeWithQueryAnnotationNamedParams_ThenReturnUser() {
+ User user = new User();
+ user.setName(USER_NAME_ADAM);
+ user.setEmail(USER_EMAIL);
+ user.setStatus(ACTIVE_STATUS);
+ userRepository.save(user);
+
+ User userByStatus = userRepository.findUserByNameLikeNamedParam("Ad");
+
+ assertThat(userByStatus.getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindUserByNameLikeWithQueryAnnotationNative_ThenReturnUser() {
+ User user = new User();
+ user.setName(USER_NAME_ADAM);
+ user.setEmail(USER_EMAIL);
+ user.setStatus(ACTIVE_STATUS);
+ userRepository.save(user);
+
+ User userByStatus = userRepository.findUserByNameLikeNative("Ad");
+
+ assertThat(userByStatus.getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindAllWithSortByName_ThenReturnUsersSorted() {
+ userRepository.save(new User(USER_NAME_ADAM, LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
+ userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS));
+
+ List usersSortByName = userRepository.findAll(new Sort(Sort.Direction.ASC, "name"));
+
+ assertThat(usersSortByName.get(0)
+ .getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test(expected = PropertyReferenceException.class)
+ public void givenUsersInDB_WhenFindAllSortWithFunction_ThenThrowException() {
+ userRepository.save(new User(USER_NAME_ADAM, LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
+ userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS));
+
+ userRepository.findAll(new Sort(Sort.Direction.ASC, "name"));
+
+ List usersSortByNameLength = userRepository.findAll(Sort.by("LENGTH(name)"));
+
+ assertThat(usersSortByNameLength.get(0)
+ .getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindAllSortWithFunctionQueryAnnotationJPQL_ThenReturnUsersSorted() {
+ userRepository.save(new User(USER_NAME_ADAM, LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
+ userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS));
+
+ userRepository.findAllUsers(Sort.by("name"));
+
+ List usersSortByNameLength = userRepository.findAllUsers(JpaSort.unsafe("LENGTH(name)"));
+
+ assertThat(usersSortByNameLength.get(0)
+ .getName()).isEqualTo(USER_NAME_ADAM);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindAllWithPageRequestQueryAnnotationJPQL_ThenReturnPageOfUsers() {
+ userRepository.save(new User(USER_NAME_ADAM, LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
+ userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE1", LocalDate.now(), USER_EMAIL4, INACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE2", LocalDate.now(), USER_EMAIL5, INACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE3", LocalDate.now(), USER_EMAIL6, INACTIVE_STATUS));
+
+ Page usersPage = userRepository.findAllUsersWithPagination(PageRequest.of(1, 3));
+
+ assertThat(usersPage.getContent()
+ .get(0)
+ .getName()).isEqualTo("SAMPLE1");
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindAllWithPageRequestQueryAnnotationNative_ThenReturnPageOfUsers() {
+ userRepository.save(new User(USER_NAME_ADAM, LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
+ userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE1", LocalDate.now(), USER_EMAIL4, INACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE2", LocalDate.now(), USER_EMAIL5, INACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE3", LocalDate.now(), USER_EMAIL6, INACTIVE_STATUS));
+
+ Page usersSortByNameLength = userRepository.findAllUsersWithPaginationNative(PageRequest.of(1, 3));
+
+ assertThat(usersSortByNameLength.getContent()
+ .get(0)
+ .getName()).isEqualTo(USER_NAME_PETER);
+ }
+
+ @Test
+ @Transactional
+ public void givenUsersInDB_WhenUpdateStatusForNameModifyingQueryAnnotationJPQL_ThenModifyMatchingUsers() {
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE1", LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE3", LocalDate.now(), USER_EMAIL4, ACTIVE_STATUS));
+
+ int updatedUsersSize = userRepository.updateUserSetStatusForName(INACTIVE_STATUS, "SAMPLE");
+
+ assertThat(updatedUsersSize).isEqualTo(2);
+ }
+
+ @Test
+ public void givenUsersInDB_WhenFindByEmailsWithDynamicQuery_ThenReturnCollection() {
+
+ User user1 = new User();
+ user1.setEmail(USER_EMAIL);
+ userRepository.save(user1);
+
+ User user2 = new User();
+ user2.setEmail(USER_EMAIL2);
+ userRepository.save(user2);
+
+ User user3 = new User();
+ user3.setEmail(USER_EMAIL3);
+ userRepository.save(user3);
+
+ Set emails = new HashSet<>();
+ emails.add(USER_EMAIL2);
+ emails.add(USER_EMAIL3);
+
+ Collection usersWithEmails = userRepository.findUserByEmails(emails);
+
+ assertThat(usersWithEmails.size()).isEqualTo(2);
+ }
+
+ @Test
+ public void givenUsersInDBWhenFindByNameListReturnCollection() {
+
+ User user1 = new User();
+ user1.setName(USER_NAME_ADAM);
+ user1.setEmail(USER_EMAIL);
+ userRepository.save(user1);
+
+ User user2 = new User();
+ user2.setName(USER_NAME_PETER);
+ user2.setEmail(USER_EMAIL2);
+ userRepository.save(user2);
+
+ List names = Arrays.asList(USER_NAME_ADAM, USER_NAME_PETER);
+
+ List usersWithNames = userRepository.findUserByNameList(names);
+
+ assertThat(usersWithNames.size()).isEqualTo(2);
+ }
+
+
+ @Test
+ @Transactional
+ public void whenInsertedWithQuery_ThenUserIsPersisted() {
+ userRepository.insertUser(USER_NAME_ADAM, 1, USER_EMAIL, ACTIVE_STATUS, true);
+ userRepository.insertUser(USER_NAME_PETER, 1, USER_EMAIL2, ACTIVE_STATUS, true);
+
+ User userAdam = userRepository.findUserByNameLike(USER_NAME_ADAM);
+ User userPeter = userRepository.findUserByNameLike(USER_NAME_PETER);
+
+ assertThat(userAdam).isNotNull();
+ assertThat(userAdam.getEmail()).isEqualTo(USER_EMAIL);
+ assertThat(userPeter).isNotNull();
+ assertThat(userPeter.getEmail()).isEqualTo(USER_EMAIL2);
+ }
+
+
+ @Test
+ @Transactional
+ public void givenTwoUsers_whenFindByNameUsr01_ThenUserUsr01() {
+ User usr01 = new User("usr01", LocalDate.now(), "usr01@baeldung.com", 1);
+ User usr02 = new User("usr02", LocalDate.now(), "usr02@baeldung.com", 1);
+
+ userRepository.save(usr01);
+ userRepository.save(usr02);
+
+ try (Stream users = userRepository.findAllByName("usr01")) {
+ assertTrue(users.allMatch(usr -> usr.equals(usr01)));
+ }
+ }
+
+ @Test
+ @Transactional
+ public void givenTwoUsers_whenFindByNameUsr00_ThenNoUsers() {
+ User usr01 = new User("usr01", LocalDate.now(), "usr01@baeldung.com", 1);
+ User usr02 = new User("usr02", LocalDate.now(), "usr02@baeldung.com", 1);
+
+ userRepository.save(usr01);
+ userRepository.save(usr02);
+
+ try (Stream users = userRepository.findAllByName("usr00")) {
+ assertEquals(0, users.count());
+ }
+ }
+
+ @Test
+ public void givenTwoUsers_whenFindUsersWithGmailAddress_ThenUserUsr02() {
+ User usr01 = new User("usr01", LocalDate.now(), "usr01@baeldung.com", 1);
+ User usr02 = new User("usr02", LocalDate.now(), "usr02@gmail.com", 1);
+
+ userRepository.save(usr01);
+ userRepository.save(usr02);
+
+ List users = userRepository.findUsersWithGmailAddress();
+ assertEquals(1, users.size());
+ assertEquals(usr02, users.get(0));
+ }
+
+ @Test
+ @Transactional
+ public void givenTwoUsers_whenDeleteAllByCreationDateAfter_ThenOneUserRemains() {
+ User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
+ User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.com", 1);
+
+ userRepository.save(usr01);
+ userRepository.save(usr02);
+
+ userRepository.deleteAllByCreationDateAfter(LocalDate.of(2018, 5, 1));
+
+ List users = userRepository.findAll();
+
+ assertEquals(1, users.size());
+ assertEquals(usr01, users.get(0));
+ }
+
+ @Test
+ public void givenTwoUsers_whenFindAllUsersByPredicates_ThenUserUsr01() {
+ User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
+ User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.org", 1);
+
+ userRepository.save(usr01);
+ userRepository.save(usr02);
+
+ List> predicates = new ArrayList<>();
+ predicates.add(usr -> usr.getCreationDate().isAfter(LocalDate.of(2017, 12, 31)));
+ predicates.add(usr -> usr.getEmail().endsWith(".com"));
+
+ List users = userRepository.findAllUsersByPredicates(predicates);
+
+ assertEquals(1, users.size());
+ assertEquals(usr01, users.get(0));
+ }
+
+ @Test
+ @Transactional
+ public void givenTwoUsers_whenDeactivateUsersNotLoggedInSince_ThenUserUsr02Deactivated() {
+ User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
+ usr01.setLastLoginDate(LocalDate.now());
+ User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.org", 1);
+ usr02.setLastLoginDate(LocalDate.of(2018, 7, 20));
+
+ userRepository.save(usr01);
+ userRepository.save(usr02);
+
+ userRepository.deactivateUsersNotLoggedInSince(LocalDate.of(2018, 8, 1));
+
+ List users = userRepository.findAllUsers(Sort.by(Sort.Order.asc("name")));
+ assertTrue(users.get(0).isActive());
+ assertFalse(users.get(1).isActive());
+ }
+
+ @Test
+ @Transactional
+ public void givenTwoUsers_whenDeleteDeactivatedUsers_ThenUserUsr02Deleted() {
+ User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
+ usr01.setLastLoginDate(LocalDate.now());
+ User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.com", 0);
+ usr02.setLastLoginDate(LocalDate.of(2018, 7, 20));
+ usr02.setActive(false);
+
+ userRepository.save(usr01);
+ userRepository.save(usr02);
+
+ int deletedUsersCount = userRepository.deleteDeactivatedUsers();
+
+ List users = userRepository.findAll();
+ assertEquals(1, users.size());
+ assertEquals(usr01, users.get(0));
+ assertEquals(1, deletedUsersCount);
+ }
+
+ @Test
+ @Transactional
+ public void givenTwoUsers_whenAddDeletedColumn_ThenUsersHaveDeletedColumn() {
+ User usr01 = new User("usr01", LocalDate.of(2018, 1, 1), "usr01@baeldung.com", 1);
+ usr01.setLastLoginDate(LocalDate.now());
+ User usr02 = new User("usr02", LocalDate.of(2018, 6, 1), "usr02@baeldung.org", 1);
+ usr02.setLastLoginDate(LocalDate.of(2018, 7, 20));
+ usr02.setActive(false);
+
+ userRepository.save(usr01);
+ userRepository.save(usr02);
+
+ userRepository.addDeletedColumn();
+
+ Query nativeQuery = entityManager.createNativeQuery("select deleted from USERS where NAME = 'usr01'");
+ assertEquals(0, nativeQuery.getResultList().get(0));
+ }
+
+ @After
+ public void cleanUp() {
+ userRepository.deleteAll();
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java
new file mode 100644
index 0000000000..99eabc8271
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java
@@ -0,0 +1,43 @@
+package com.baeldung.boot.daos;
+
+import com.baeldung.boot.Application;
+import com.baeldung.boot.domain.User;
+import com.baeldung.util.BaeldungPostgresqlContainer;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.transaction.annotation.Transactional;
+import org.testcontainers.containers.PostgreSQLContainer;
+
+import java.time.LocalDate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Created by adam.
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Application.class)
+@ActiveProfiles({"tc", "tc-auto"})
+public class UserRepositoryTCAutoLiveTest extends UserRepositoryCommon {
+
+ @ClassRule
+ public static PostgreSQLContainer postgreSQLContainer = BaeldungPostgresqlContainer.getInstance();
+
+ @Test
+ @Transactional
+ public void givenUsersInDB_WhenUpdateStatusForNameModifyingQueryAnnotationNativePostgres_ThenModifyMatchingUsers() {
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE1", LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE3", LocalDate.now(), USER_EMAIL4, ACTIVE_STATUS));
+ userRepository.flush();
+
+ int updatedUsersSize = userRepository.updateUserSetStatusForNameNativePostgres(INACTIVE_STATUS, "SAMPLE");
+
+ assertThat(updatedUsersSize).isEqualTo(2);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/UserRepositoryTCLiveTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/UserRepositoryTCLiveTest.java
new file mode 100644
index 0000000000..be8843c166
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/daos/UserRepositoryTCLiveTest.java
@@ -0,0 +1,58 @@
+package com.baeldung.boot.daos;
+
+import com.baeldung.boot.Application;
+import com.baeldung.boot.domain.User;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.util.TestPropertyValues;
+import org.springframework.context.ApplicationContextInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.transaction.annotation.Transactional;
+import org.testcontainers.containers.PostgreSQLContainer;
+
+import java.time.LocalDate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Application.class)
+@ActiveProfiles("tc")
+@ContextConfiguration(initializers = {UserRepositoryTCLiveTest.Initializer.class})
+public class UserRepositoryTCLiveTest extends UserRepositoryCommon {
+
+ @ClassRule
+ public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer("postgres:11.1")
+ .withDatabaseName("integration-tests-db")
+ .withUsername("sa")
+ .withPassword("sa");
+
+ @Test
+ @Transactional
+ public void givenUsersInDB_WhenUpdateStatusForNameModifyingQueryAnnotationNative_ThenModifyMatchingUsers() {
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE1", LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, ACTIVE_STATUS));
+ userRepository.save(new User("SAMPLE3", LocalDate.now(), USER_EMAIL4, ACTIVE_STATUS));
+ userRepository.flush();
+
+ int updatedUsersSize = userRepository.updateUserSetStatusForNameNativePostgres(INACTIVE_STATUS, "SAMPLE");
+
+ assertThat(updatedUsersSize).isEqualTo(2);
+ }
+
+ static class Initializer
+ implements ApplicationContextInitializer {
+ public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
+ TestPropertyValues.of(
+ "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(),
+ "spring.datasource.username=" + postgreSQLContainer.getUsername(),
+ "spring.datasource.password=" + postgreSQLContainer.getPassword()
+ ).applyTo(configurableApplicationContext.getEnvironment());
+ }
+ }
+}
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/web/controllers/CustomerController.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/web/controllers/CustomerController.java
similarity index 100%
rename from persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/web/controllers/CustomerController.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/boot/web/controllers/CustomerController.java
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/ProductRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/multipledb/ProductRepositoryIntegrationTest.java
similarity index 97%
rename from persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/ProductRepositoryIntegrationTest.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/multipledb/ProductRepositoryIntegrationTest.java
index 2c965f72f3..cdbb307d7f 100644
--- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/multipledb/ProductRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/multipledb/ProductRepositoryIntegrationTest.java
@@ -18,12 +18,10 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
-import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
-import com.baeldung.multipledb.PersistenceProductConfiguration;
import com.baeldung.multipledb.dao.product.ProductRepository;
import com.baeldung.multipledb.model.product.ProductMultipleDB;
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
index ba94fc111b..19fdf118ae 100644
--- 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
@@ -1,6 +1,6 @@
package com.baeldung.osiv;
-import com.baeldung.model.User;
+import com.baeldung.model.BasicUser;
import com.baeldung.repository.UserRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -32,7 +32,7 @@ class UserControllerIntegrationTest {
@BeforeEach
void setUp() {
- User user = new User();
+ BasicUser user = new BasicUser();
user.setUsername("root");
user.setPermissions(new HashSet<>(Arrays.asList("PERM_READ", "PERM_WRITE")));
diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/EmployeeRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/repository/EmployeeRepositoryIntegrationTest.java
similarity index 89%
rename from persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/EmployeeRepositoryIntegrationTest.java
rename to persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/repository/EmployeeRepositoryIntegrationTest.java
index ebeed276c9..0fc9918701 100644
--- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/repository/EmployeeRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/repository/EmployeeRepositoryIntegrationTest.java
@@ -5,13 +5,14 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
+import com.baeldung.boot.Application;
import com.baeldung.entity.Employee;
@RunWith(SpringRunner.class)
-@DataJpaTest
+@SpringBootTest(classes = Application.class)
public class EmployeeRepositoryIntegrationTest {
private static final Employee EMPLOYEE1 = new Employee(1L, "John");
@@ -25,7 +26,7 @@ public class EmployeeRepositoryIntegrationTest {
employeeRepository.save(EMPLOYEE1);
assertEmployeePersisted(EMPLOYEE1);
}
-
+
@Test
public void givenEmployeeEntity_whenInsertWithSaveAndFlush_ThenEmployeeIsPersisted() {
employeeRepository.saveAndFlush(EMPLOYEE2);
diff --git a/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/util/BaeldungPostgresqlContainer.java b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/util/BaeldungPostgresqlContainer.java
new file mode 100644
index 0000000000..e5ad2dd448
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/java/com/baeldung/util/BaeldungPostgresqlContainer.java
@@ -0,0 +1,35 @@
+package com.baeldung.util;
+
+import org.testcontainers.containers.PostgreSQLContainer;
+
+public class BaeldungPostgresqlContainer extends PostgreSQLContainer {
+
+ private static final String IMAGE_VERSION = "postgres:11.1";
+
+ private static BaeldungPostgresqlContainer container;
+
+
+ private BaeldungPostgresqlContainer() {
+ super(IMAGE_VERSION);
+ }
+
+ public static BaeldungPostgresqlContainer getInstance() {
+ if (container == null) {
+ container = new BaeldungPostgresqlContainer();
+ }
+ return container;
+ }
+
+ @Override
+ public void start() {
+ super.start();
+ System.setProperty("DB_URL", container.getJdbcUrl());
+ System.setProperty("DB_USERNAME", container.getUsername());
+ System.setProperty("DB_PASSWORD", container.getPassword());
+ }
+
+ @Override
+ public void stop() {
+ //do nothing, JVM handles shut down
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-2/src/main/resources/application-batchinserts.properties b/persistence-modules/spring-data-jpa-3/src/test/resources/application-batchinserts.properties
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/main/resources/application-batchinserts.properties
rename to persistence-modules/spring-data-jpa-3/src/test/resources/application-batchinserts.properties
diff --git a/persistence-modules/spring-data-jpa-3/src/test/resources/application-tc-auto.properties b/persistence-modules/spring-data-jpa-3/src/test/resources/application-tc-auto.properties
new file mode 100644
index 0000000000..c3005d861f
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/resources/application-tc-auto.properties
@@ -0,0 +1,4 @@
+# configuration for test containers testing
+spring.datasource.url=${DB_URL}
+spring.datasource.username=${DB_USERNAME}
+spring.datasource.password=${DB_PASSWORD}
diff --git a/persistence-modules/spring-data-jpa-3/src/test/resources/application-tc.properties b/persistence-modules/spring-data-jpa-3/src/test/resources/application-tc.properties
new file mode 100644
index 0000000000..3bf8693d53
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-3/src/test/resources/application-tc.properties
@@ -0,0 +1,4 @@
+# configuration for Test Containers testing
+spring.datasource.driver-class-name=org.postgresql.Driver
+spring.jpa.hibernate.ddl-auto=create-drop
+spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
diff --git a/persistence-modules/spring-data-jpa-4/README.md b/persistence-modules/spring-data-jpa-4/README.md
new file mode 100644
index 0000000000..931455224f
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-4/README.md
@@ -0,0 +1,12 @@
+### Relevant Articles:
+- [Derived Query Methods in Spring Data JPA Repositories](https://www.baeldung.com/spring-data-derived-queries)
+- [LIKE Queries in Spring JPA Repositories](https://www.baeldung.com/spring-jpa-like-queries)
+
+### Eclipse Config
+After importing the project into Eclipse, you may see the following error:
+"No persistence xml file found in project"
+
+This can be ignored:
+- Project -> Properties -> Java Persistance -> JPA -> Error/Warnings -> Select Ignore on "No persistence xml file found in project"
+Or:
+- Eclipse -> Preferences - Validation - disable the "Build" execution of the JPA Validator
diff --git a/persistence-modules/spring-data-jpa-4/pom.xml b/persistence-modules/spring-data-jpa-4/pom.xml
new file mode 100644
index 0000000000..2d06b52134
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-4/pom.xml
@@ -0,0 +1,37 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ spring-data-jpa-4
+ spring-data-jpa-4
+
+
+ parent-boot-2
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/Application.java b/persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/Application.java
new file mode 100644
index 0000000000..37dbe7dab8
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/Application.java
@@ -0,0 +1,13 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/derivedquery/entity/User.java b/persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/derivedquery/entity/User.java
similarity index 95%
rename from persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/derivedquery/entity/User.java
rename to persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/derivedquery/entity/User.java
index e6d38f775b..49e824f09f 100644
--- a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/derivedquery/entity/User.java
+++ b/persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/derivedquery/entity/User.java
@@ -1,70 +1,70 @@
-package com.baeldung.derivedquery.entity;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.time.ZonedDateTime;
-
-@Table(name = "users")
-@Entity
-public class User {
-
- @Id
- @GeneratedValue
- private Integer id;
- private String name;
- private Integer age;
- private ZonedDateTime birthDate;
- private Boolean active;
-
- public User() {
- }
-
- public User(String name, Integer age, ZonedDateTime birthDate, Boolean active) {
- this.name = name;
- this.age = age;
- this.birthDate = birthDate;
- this.active = active;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- public ZonedDateTime getBirthDate() {
- return birthDate;
- }
-
- public void setBirthDate(ZonedDateTime birthDate) {
- this.birthDate = birthDate;
- }
-
- public Boolean getActive() {
- return active;
- }
-
- public void setActive(Boolean active) {
- this.active = active;
- }
-}
+package com.baeldung.derivedquery.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.time.ZonedDateTime;
+
+@Table(name = "users")
+@Entity
+public class User {
+
+ @Id
+ @GeneratedValue
+ private Integer id;
+ private String name;
+ private Integer age;
+ private ZonedDateTime birthDate;
+ private Boolean active;
+
+ public User() {
+ }
+
+ public User(String name, Integer age, ZonedDateTime birthDate, Boolean active) {
+ this.name = name;
+ this.age = age;
+ this.birthDate = birthDate;
+ this.active = active;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public ZonedDateTime getBirthDate() {
+ return birthDate;
+ }
+
+ public void setBirthDate(ZonedDateTime birthDate) {
+ this.birthDate = birthDate;
+ }
+
+ public Boolean getActive() {
+ return active;
+ }
+
+ public void setActive(Boolean active) {
+ this.active = active;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java b/persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java
similarity index 96%
rename from persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java
rename to persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java
index a23855d96d..e613ee1531 100644
--- a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java
+++ b/persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/derivedquery/repository/UserRepository.java
@@ -1,60 +1,60 @@
-package com.baeldung.derivedquery.repository;
-
-import com.baeldung.derivedquery.entity.User;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.time.ZonedDateTime;
-import java.util.Collection;
-import java.util.List;
-
-public interface UserRepository extends JpaRepository {
-
- List findByName(String name);
-
- List findByNameIs(String name);
-
- List findByNameEquals(String name);
-
- List findByNameIsNull();
-
- List findByNameNot(String name);
-
- List findByNameIsNot(String name);
-
- List findByNameStartingWith(String name);
-
- List findByNameEndingWith(String name);
-
- List findByNameContaining(String name);
-
- List findByNameLike(String name);
-
- List findByAgeLessThan(Integer age);
-
- List findByAgeLessThanEqual(Integer age);
-
- List findByAgeGreaterThan(Integer age);
-
- List findByAgeGreaterThanEqual(Integer age);
-
- List findByAgeBetween(Integer startAge, Integer endAge);
-
- List findByBirthDateAfter(ZonedDateTime birthDate);
-
- List findByBirthDateBefore(ZonedDateTime birthDate);
-
- List findByActiveTrue();
-
- List findByActiveFalse();
-
- List findByAgeIn(Collection ages);
-
- List findByNameOrBirthDate(String name, ZonedDateTime birthDate);
-
- List findByNameOrBirthDateAndActive(String name, ZonedDateTime birthDate, Boolean active);
-
- List findByNameOrderByName(String name);
-
- List findByNameOrderByNameDesc(String name);
-
-}
+package com.baeldung.derivedquery.repository;
+
+import com.baeldung.derivedquery.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.time.ZonedDateTime;
+import java.util.Collection;
+import java.util.List;
+
+public interface UserRepository extends JpaRepository {
+
+ List findByName(String name);
+
+ List findByNameIs(String name);
+
+ List findByNameEquals(String name);
+
+ List findByNameIsNull();
+
+ List findByNameNot(String name);
+
+ List findByNameIsNot(String name);
+
+ List findByNameStartingWith(String name);
+
+ List findByNameEndingWith(String name);
+
+ List findByNameContaining(String name);
+
+ List findByNameLike(String name);
+
+ List findByAgeLessThan(Integer age);
+
+ List findByAgeLessThanEqual(Integer age);
+
+ List findByAgeGreaterThan(Integer age);
+
+ List findByAgeGreaterThanEqual(Integer age);
+
+ List findByAgeBetween(Integer startAge, Integer endAge);
+
+ List findByBirthDateAfter(ZonedDateTime birthDate);
+
+ List findByBirthDateBefore(ZonedDateTime birthDate);
+
+ List findByActiveTrue();
+
+ List findByActiveFalse();
+
+ List findByAgeIn(Collection ages);
+
+ List findByNameOrBirthDate(String name, ZonedDateTime birthDate);
+
+ List findByNameOrBirthDateAndActive(String name, ZonedDateTime birthDate, Boolean active);
+
+ List findByNameOrderByName(String name);
+
+ List findByNameOrderByNameDesc(String name);
+
+}
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/model/Movie.java b/persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/like/model/Movie.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/model/Movie.java
rename to persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/like/model/Movie.java
diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/repository/MovieRepository.java b/persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/like/repository/MovieRepository.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/repository/MovieRepository.java
rename to persistence-modules/spring-data-jpa-4/src/main/java/com/baeldung/like/repository/MovieRepository.java
diff --git a/persistence-modules/spring-data-jpa-4/src/main/resources/application.properties b/persistence-modules/spring-data-jpa-4/src/main/resources/application.properties
new file mode 100644
index 0000000000..72fc330767
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-4/src/main/resources/application.properties
@@ -0,0 +1 @@
+spring.jpa.show-sql=true
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryTest.java b/persistence-modules/spring-data-jpa-4/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java
similarity index 94%
rename from persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryTest.java
rename to persistence-modules/spring-data-jpa-4/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java
index 188ed5d4d0..22d2b7c00d 100644
--- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryTest.java
+++ b/persistence-modules/spring-data-jpa-4/src/test/java/com/baeldung/derivedquery/repository/UserRepositoryIntegrationTest.java
@@ -1,172 +1,172 @@
-package com.baeldung.derivedquery.repository;
-
-import com.baeldung.Application;
-import com.baeldung.derivedquery.entity.User;
-import com.baeldung.derivedquery.repository.UserRepository;
-import java.time.ZonedDateTime;
-import java.util.Arrays;
-import java.util.List;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import static org.junit.Assert.assertEquals;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(classes = Application.class)
-public class UserRepositoryTest {
-
- private static final String USER_NAME_ADAM = "Adam";
- private static final String USER_NAME_EVE = "Eve";
- private static final ZonedDateTime BIRTHDATE = ZonedDateTime.now();
-
- @Autowired
- private UserRepository userRepository;
-
- @Before
- public void setUp() {
-
- User user1 = new User(USER_NAME_ADAM, 25, BIRTHDATE, true);
- User user2 = new User(USER_NAME_ADAM, 20, BIRTHDATE, false);
- User user3 = new User(USER_NAME_EVE, 20, BIRTHDATE, true);
- User user4 = new User(null, 30, BIRTHDATE, false);
-
- userRepository.saveAll(Arrays.asList(user1, user2, user3, user4));
- }
-
- @After
- public void tearDown() {
-
- userRepository.deleteAll();
- }
-
- @Test
- public void whenFindByName_thenReturnsCorrectResult() {
-
- assertEquals(2, userRepository.findByName(USER_NAME_ADAM).size());
- }
-
- @Test
- public void whenFindByNameIsNull_thenReturnsCorrectResult() {
-
- assertEquals(1, userRepository.findByNameIsNull().size());
- }
-
- @Test
- public void whenFindByNameNot_thenReturnsCorrectResult() {
-
- assertEquals(USER_NAME_EVE, userRepository.findByNameNot(USER_NAME_ADAM).get(0).getName());
- }
-
- @Test
- public void whenFindByNameStartingWith_thenReturnsCorrectResult() {
-
- assertEquals(2, userRepository.findByNameStartingWith("A").size());
- }
-
- @Test
- public void whenFindByNameEndingWith_thenReturnsCorrectResult() {
-
- assertEquals(1, userRepository.findByNameEndingWith("e").size());
- }
-
- @Test
- public void whenByNameContaining_thenReturnsCorrectResult() {
-
- assertEquals(1, userRepository.findByNameContaining("v").size());
- }
-
-
- @Test
- public void whenByNameLike_thenReturnsCorrectResult() {
-
- assertEquals(2, userRepository.findByNameEndingWith("%d%m").size());
- }
-
- @Test
- public void whenByAgeLessThan_thenReturnsCorrectResult() {
-
- assertEquals(2, userRepository.findByAgeLessThan(25).size());
- }
-
-
- @Test
- public void whenByAgeLessThanEqual_thenReturnsCorrectResult() {
-
- assertEquals(3, userRepository.findByAgeLessThanEqual(25).size());
- }
-
- @Test
- public void whenByAgeGreaterThan_thenReturnsCorrectResult() {
-
- assertEquals(1, userRepository.findByAgeGreaterThan(25).size());
- }
-
- @Test
- public void whenByAgeGreaterThanEqual_thenReturnsCorrectResult() {
-
- assertEquals(2, userRepository.findByAgeGreaterThanEqual(25).size());
- }
-
- @Test
- public void whenByAgeBetween_thenReturnsCorrectResult() {
-
- assertEquals(4, userRepository.findByAgeBetween(20, 30).size());
- }
-
- @Test
- public void whenByBirthDateAfter_thenReturnsCorrectResult() {
-
- final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
- assertEquals(4, userRepository.findByBirthDateAfter(yesterday).size());
- }
-
- @Test
- public void whenByBirthDateBefore_thenReturnsCorrectResult() {
-
- final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
- assertEquals(0, userRepository.findByBirthDateBefore(yesterday).size());
- }
-
- @Test
- public void whenByActiveTrue_thenReturnsCorrectResult() {
-
- assertEquals(2, userRepository.findByActiveTrue().size());
- }
-
- @Test
- public void whenByActiveFalse_thenReturnsCorrectResult() {
-
- assertEquals(2, userRepository.findByActiveFalse().size());
- }
-
-
- @Test
- public void whenByAgeIn_thenReturnsCorrectResult() {
-
- final List ages = Arrays.asList(20, 25);
- assertEquals(3, userRepository.findByAgeIn(ages).size());
- }
-
- @Test
- public void whenByNameOrBirthDate() {
-
- assertEquals(4, userRepository.findByNameOrBirthDate(USER_NAME_ADAM, BIRTHDATE).size());
- }
-
- @Test
- public void whenByNameOrBirthDateAndActive() {
-
- assertEquals(3, userRepository.findByNameOrBirthDateAndActive(USER_NAME_ADAM, BIRTHDATE, false).size());
- }
-
- @Test
- public void whenByNameOrderByName() {
-
- assertEquals(2, userRepository.findByNameOrderByName(USER_NAME_ADAM).size());
- }
+package com.baeldung.derivedquery.repository;
+
+import com.baeldung.Application;
+import com.baeldung.derivedquery.entity.User;
+import com.baeldung.derivedquery.repository.UserRepository;
+import java.time.ZonedDateTime;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Application.class)
+public class UserRepositoryIntegrationTest {
+
+ private static final String USER_NAME_ADAM = "Adam";
+ private static final String USER_NAME_EVE = "Eve";
+ private static final ZonedDateTime BIRTHDATE = ZonedDateTime.now();
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Before
+ public void setUp() {
+
+ User user1 = new User(USER_NAME_ADAM, 25, BIRTHDATE, true);
+ User user2 = new User(USER_NAME_ADAM, 20, BIRTHDATE, false);
+ User user3 = new User(USER_NAME_EVE, 20, BIRTHDATE, true);
+ User user4 = new User(null, 30, BIRTHDATE, false);
+
+ userRepository.saveAll(Arrays.asList(user1, user2, user3, user4));
+ }
+
+ @After
+ public void tearDown() {
+
+ userRepository.deleteAll();
+ }
+
+ @Test
+ public void whenFindByName_thenReturnsCorrectResult() {
+
+ assertEquals(2, userRepository.findByName(USER_NAME_ADAM).size());
+ }
+
+ @Test
+ public void whenFindByNameIsNull_thenReturnsCorrectResult() {
+
+ assertEquals(1, userRepository.findByNameIsNull().size());
+ }
+
+ @Test
+ public void whenFindByNameNot_thenReturnsCorrectResult() {
+
+ assertEquals(USER_NAME_EVE, userRepository.findByNameNot(USER_NAME_ADAM).get(0).getName());
+ }
+
+ @Test
+ public void whenFindByNameStartingWith_thenReturnsCorrectResult() {
+
+ assertEquals(2, userRepository.findByNameStartingWith("A").size());
+ }
+
+ @Test
+ public void whenFindByNameEndingWith_thenReturnsCorrectResult() {
+
+ assertEquals(1, userRepository.findByNameEndingWith("e").size());
+ }
+
+ @Test
+ public void whenByNameContaining_thenReturnsCorrectResult() {
+
+ assertEquals(1, userRepository.findByNameContaining("v").size());
+ }
+
+
+ @Test
+ public void whenByNameLike_thenReturnsCorrectResult() {
+
+ assertEquals(2, userRepository.findByNameEndingWith("m").size());
+ }
+
+ @Test
+ public void whenByAgeLessThan_thenReturnsCorrectResult() {
+
+ assertEquals(2, userRepository.findByAgeLessThan(25).size());
+ }
+
+
+ @Test
+ public void whenByAgeLessThanEqual_thenReturnsCorrectResult() {
+
+ assertEquals(3, userRepository.findByAgeLessThanEqual(25).size());
+ }
+
+ @Test
+ public void whenByAgeGreaterThan_thenReturnsCorrectResult() {
+
+ assertEquals(1, userRepository.findByAgeGreaterThan(25).size());
+ }
+
+ @Test
+ public void whenByAgeGreaterThanEqual_thenReturnsCorrectResult() {
+
+ assertEquals(2, userRepository.findByAgeGreaterThanEqual(25).size());
+ }
+
+ @Test
+ public void whenByAgeBetween_thenReturnsCorrectResult() {
+
+ assertEquals(4, userRepository.findByAgeBetween(20, 30).size());
+ }
+
+ @Test
+ public void whenByBirthDateAfter_thenReturnsCorrectResult() {
+
+ final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
+ assertEquals(4, userRepository.findByBirthDateAfter(yesterday).size());
+ }
+
+ @Test
+ public void whenByBirthDateBefore_thenReturnsCorrectResult() {
+
+ final ZonedDateTime yesterday = BIRTHDATE.minusDays(1);
+ assertEquals(0, userRepository.findByBirthDateBefore(yesterday).size());
+ }
+
+ @Test
+ public void whenByActiveTrue_thenReturnsCorrectResult() {
+
+ assertEquals(2, userRepository.findByActiveTrue().size());
+ }
+
+ @Test
+ public void whenByActiveFalse_thenReturnsCorrectResult() {
+
+ assertEquals(2, userRepository.findByActiveFalse().size());
+ }
+
+
+ @Test
+ public void whenByAgeIn_thenReturnsCorrectResult() {
+
+ final List ages = Arrays.asList(20, 25);
+ assertEquals(3, userRepository.findByAgeIn(ages).size());
+ }
+
+ @Test
+ public void whenByNameOrBirthDate() {
+
+ assertEquals(4, userRepository.findByNameOrBirthDate(USER_NAME_ADAM, BIRTHDATE).size());
+ }
+
+ @Test
+ public void whenByNameOrBirthDateAndActive() {
+
+ assertEquals(3, userRepository.findByNameOrBirthDateAndActive(USER_NAME_ADAM, BIRTHDATE, false).size());
+ }
+
+ @Test
+ public void whenByNameOrderByName() {
+
+ assertEquals(2, userRepository.findByNameOrderByName(USER_NAME_ADAM).size());
+ }
}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/like/MovieRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-4/src/test/java/com/baeldung/like/MovieRepositoryIntegrationTest.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/like/MovieRepositoryIntegrationTest.java
rename to persistence-modules/spring-data-jpa-4/src/test/java/com/baeldung/like/MovieRepositoryIntegrationTest.java
diff --git a/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-cleanup.sql b/persistence-modules/spring-data-jpa-4/src/test/resources/test-movie-cleanup.sql
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-cleanup.sql
rename to persistence-modules/spring-data-jpa-4/src/test/resources/test-movie-cleanup.sql
diff --git a/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-data.sql b/persistence-modules/spring-data-jpa-4/src/test/resources/test-movie-data.sql
similarity index 100%
rename from persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-data.sql
rename to persistence-modules/spring-data-jpa-4/src/test/resources/test-movie-data.sql
diff --git a/persistence-modules/spring-data-jpa/README.md b/persistence-modules/spring-data-jpa/README.md
index 4b4a590e10..1c43edf42b 100644
--- a/persistence-modules/spring-data-jpa/README.md
+++ b/persistence-modules/spring-data-jpa/README.md
@@ -3,24 +3,16 @@
## Spring Data JPA Example Project
### Relevant Articles:
-- [Spring JPA – Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases)
-- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
-- [An Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced)
-- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
-- [Spring Data Java 8 Support](http://www.baeldung.com/spring-data-java-8)
-- [A Simple Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging)
+- [Spring JPA – Multiple Databases](https://www.baeldung.com/spring-data-jpa-multiple-databases)
+- [Spring Data JPA – Adding a Method in All Repositories](https://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
+- [An Advanced Tagging Implementation with JPA](https://www.baeldung.com/jpa-tagging-advanced)
+- [Spring Data Annotations](https://www.baeldung.com/spring-data-annotations)
+- [Spring Data Java 8 Support](https://www.baeldung.com/spring-data-java-8)
+- [A Simple Tagging Implementation with JPA](https://www.baeldung.com/jpa-tagging)
- [Spring Data Composable Repositories](https://www.baeldung.com/spring-data-composable-repositories)
- [Query Entities by Dates and Times with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-query-by-date)
- [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd)
- [Spring Data – CrudRepository save() Method](https://www.baeldung.com/spring-data-crud-repository-save)
-- [Limiting Query Results with JPA and Spring Data JPA](https://www.baeldung.com/jpa-limit-query-results)
-- [Sorting Query Results with Spring Data](https://www.baeldung.com/spring-data-sorting)
-- [INSERT Statement in JPA](https://www.baeldung.com/jpa-insert)
-- [Pagination and Sorting using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-pagination-sorting)
-- [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example)
-- [DB Integration Tests with Spring Boot and Testcontainers](https://www.baeldung.com/spring-boot-testcontainers-integration-test)
-- [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation)
-- [Spring Data JPA Batch Inserts](https://www.baeldung.com/spring-data-jpa-batch-inserts)
### Eclipse Config
After importing the project into Eclipse, you may see the following error:
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/Application.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/Application.java
index 1f078801e2..c66921a3ca 100644
--- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/Application.java
+++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/Application.java
@@ -5,7 +5,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import com.baeldung.boot.daos.impl.ExtendedRepositoryImpl;
-import com.baeldung.multipledb.MultipleDbApplication;
@SpringBootApplication
@EnableJpaRepositories(repositoryBaseClass = ExtendedRepositoryImpl.class)
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/config/PersistenceConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/config/PersistenceConfiguration.java
index 35a603d9f4..76d5887030 100644
--- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/config/PersistenceConfiguration.java
+++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/config/PersistenceConfiguration.java
@@ -1,11 +1,13 @@
package com.baeldung.boot.config;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
import com.baeldung.boot.services.IBarService;
import com.baeldung.boot.services.impl.BarSpringDataJpaService;
-import org.springframework.context.annotation.*;
-import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
-import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
-import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@Profile("!tc")
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/impl/CustomItemTypeRepositoryImpl.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/impl/CustomItemTypeRepositoryImpl.java
index d7cba7c2c6..e057f36b26 100644
--- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/impl/CustomItemTypeRepositoryImpl.java
+++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/impl/CustomItemTypeRepositoryImpl.java
@@ -2,8 +2,6 @@ package com.baeldung.boot.daos.impl;
import javax.persistence.EntityManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@@ -13,8 +11,6 @@ import com.baeldung.boot.domain.ItemType;
@Repository
public class CustomItemTypeRepositoryImpl implements CustomItemTypeRepository {
- private static final Logger LOGGER = LoggerFactory.getLogger(CustomItemTypeRepositoryImpl.class);
-
@Autowired
private EntityManager entityManager;
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/services/impl/AbstractService.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/services/impl/AbstractService.java
index 8e4f643adc..f88d018bbb 100644
--- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/services/impl/AbstractService.java
+++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/services/impl/AbstractService.java
@@ -31,7 +31,7 @@ public abstract class AbstractService implements IOperat
@Override
public Page findPaginated(final int page, final int size) {
- return getDao().findAll(new PageRequest(page, size));
+ return getDao().findAll(PageRequest.of(page, size));
}
// write
diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/dao/product/ProductRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/dao/product/ProductRepository.java
index 022099eed0..9b235776dc 100755
--- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/dao/product/ProductRepository.java
+++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/dao/product/ProductRepository.java
@@ -1,13 +1,9 @@
package com.baeldung.multipledb.dao.product;
-import java.util.List;
-
-import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.baeldung.multipledb.model.product.ProductMultipleDB;
public interface ProductRepository extends PagingAndSortingRepository {
- List findAllByPrice(double price, Pageable pageable);
-}
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/ArticleRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/ArticleRepositoryIntegrationTest.java
index dfb04b3dfb..20fc3cbeaf 100644
--- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/ArticleRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/ArticleRepositoryIntegrationTest.java
@@ -1,24 +1,19 @@
package com.baeldung.boot.daos;
-import com.baeldung.boot.Application;
-import com.baeldung.boot.config.PersistenceConfiguration;
-import com.baeldung.boot.daos.ArticleRepository;
-import com.baeldung.boot.domain.Article;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.context.annotation.Import;
-import org.springframework.test.context.junit4.SpringRunner;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.boot.domain.Article;
@RunWith(SpringRunner.class)
@DataJpaTest(properties="spring.datasource.data=classpath:import_entities.sql")
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/ExtendedStudentRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/ExtendedStudentRepositoryIntegrationTest.java
index 66de5911db..71f92c94ab 100644
--- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/ExtendedStudentRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/ExtendedStudentRepositoryIntegrationTest.java
@@ -1,9 +1,10 @@
package com.baeldung.boot.daos;
-import com.baeldung.boot.Application;
-import com.baeldung.boot.config.PersistenceConfiguration;
-import com.baeldung.boot.daos.ExtendedStudentRepository;
-import com.baeldung.boot.domain.Student;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+
+import javax.annotation.Resource;
import org.junit.Before;
import org.junit.Test;
@@ -12,10 +13,8 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
-import javax.annotation.Resource;
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
+import com.baeldung.boot.Application;
+import com.baeldung.boot.domain.Student;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {Application.class})
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/InventoryRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/InventoryRepositoryIntegrationTest.java
index 877e59d5a2..5d73e261a4 100644
--- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/InventoryRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/InventoryRepositoryIntegrationTest.java
@@ -1,23 +1,20 @@
package com.baeldung.boot.daos;
-import com.baeldung.boot.Application;
-import com.baeldung.boot.config.PersistenceConfiguration;
-import com.baeldung.boot.daos.InventoryRepository;
-import com.baeldung.boot.domain.MerchandiseEntity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.math.BigDecimal;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import java.math.BigDecimal;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.boot.Application;
+import com.baeldung.boot.domain.MerchandiseEntity;
+
@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
public class InventoryRepositoryIntegrationTest {
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/JpaRepositoriesIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/JpaRepositoriesIntegrationTest.java
index 30925d9b68..9e4b78dce3 100644
--- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/JpaRepositoriesIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/JpaRepositoriesIntegrationTest.java
@@ -13,21 +13,12 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
-import com.baeldung.boot.Application;
-import com.baeldung.boot.config.PersistenceConfiguration;
-import com.baeldung.boot.daos.ItemTypeRepository;
-import com.baeldung.boot.daos.LocationRepository;
-import com.baeldung.boot.daos.ReadOnlyLocationRepository;
-import com.baeldung.boot.daos.StoreRepository;
import com.baeldung.boot.domain.Item;
import com.baeldung.boot.domain.ItemType;
import com.baeldung.boot.domain.Location;
import com.baeldung.boot.domain.Store;
-import com.baeldung.multipledb.PersistenceProductConfiguration;
-import com.baeldung.multipledb.PersistenceUserConfiguration;
@RunWith(SpringRunner.class)
@DataJpaTest(properties="spring.datasource.data=classpath:import_entities.sql")
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java
index ab8d97bd75..99eabc8271 100644
--- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java
+++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java
@@ -25,7 +25,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class UserRepositoryTCAutoLiveTest extends UserRepositoryCommon {
@ClassRule
- public static PostgreSQLContainer postgreSQLContainer = BaeldungPostgresqlContainer.getInstance();
+ public static PostgreSQLContainer postgreSQLContainer = BaeldungPostgresqlContainer.getInstance();
@Test
@Transactional
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/services/FooServicePersistenceIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/services/FooServicePersistenceIntegrationTest.java
index f0e4aa7317..72de4918a2 100644
--- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/services/FooServicePersistenceIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/services/FooServicePersistenceIntegrationTest.java
@@ -1,10 +1,7 @@
package com.baeldung.boot.services;
-import com.baeldung.boot.Application;
-import com.baeldung.boot.config.PersistenceConfiguration;
-import com.baeldung.boot.domain.Foo;
-import com.baeldung.boot.services.IFooService;
-import com.baeldung.boot.services.IOperations;
+import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
+import static org.junit.Assert.assertNotNull;
import org.junit.Ignore;
import org.junit.Test;
@@ -13,12 +10,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
-import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
-import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
-import static org.junit.Assert.assertNotNull;
+import com.baeldung.boot.Application;
+import com.baeldung.boot.domain.Foo;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/services/SpringDataJPABarAuditIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/services/SpringDataJPABarAuditIntegrationTest.java
index 810cf70769..644d1ec805 100644
--- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/services/SpringDataJPABarAuditIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/services/SpringDataJPABarAuditIntegrationTest.java
@@ -18,14 +18,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
-import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
import com.baeldung.boot.Application;
-import com.baeldung.boot.config.PersistenceConfiguration;
import com.baeldung.boot.domain.Bar;
-import com.baeldung.boot.services.IBarService;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
diff --git a/persistence-modules/spring-mybatis/pom.xml b/persistence-modules/spring-mybatis/pom.xml
index ecdcd1d923..9946c937c8 100644
--- a/persistence-modules/spring-mybatis/pom.xml
+++ b/persistence-modules/spring-mybatis/pom.xml
@@ -9,7 +9,7 @@
com.baeldung
parent-boot-2
- 1.0.0-SNAPSHOT
+ 0.0.1-SNAPSHOT
../../parent-boot-2
@@ -34,6 +34,7 @@
org.mybatis.spring.boot
mybatis-spring-boot-starter
+ ${mybatis-spring-boot-starter.version}
diff --git a/pom.xml b/pom.xml
index 3624f51a01..be440ad033 100644
--- a/pom.xml
+++ b/pom.xml
@@ -923,7 +923,6 @@
spring-boot-di
greeter-spring-boot-autoconfigure
greeter-spring-boot-sample-app
- persistence-modules/spring-boot-h2/spring-boot-h2-database
spring-boot-jasypt
spring-boot-keycloak
spring-boot-mvc
@@ -948,16 +947,12 @@
spring-cloud/spring-cloud-data-flow/time-processor
spring-cloud/spring-cloud-data-flow/time-source
spring-cucumber
- persistence-modules/spring-data-keyvalue
spring-data-rest
spring-dispatcher-servlet
spring-drools
spring-di
spring-ehcache
spring-freemarker
- persistence-modules/spring-hibernate-3
- persistence-modules/spring-hibernate4
- persistence-modules/spring-mybatis
spring-integration
spring-jenkins-pipeline
spring-jersey
@@ -1014,11 +1009,6 @@
spring-vault
spring-vertx
spring-zuul/spring-zuul-foos-resource
- persistence-modules/hibernate-mapping
- persistence-modules/spring-data-dynamodb
- persistence-modules/spring-data-eclipselink
- persistence-modules/spring-data-solr
- persistence-modules/spring-hibernate-5
spring-boot-flowable
spring-security-kerberos
@@ -1651,7 +1641,7 @@
core-java-modules/core-java-concurrency-advanced
core-java-modules/core-java-concurrency-advanced-2
core-java-modules/core-java-concurrency-advanced-3
- core-kotlin
+ core-kotlin
core-kotlin-2
jenkins/plugins
@@ -1661,6 +1651,7 @@
libraries
persistence-modules/hibernate5
+ persistence-modules/hibernate-mapping
persistence-modules/java-jpa
persistence-modules/java-jpa-2
persistence-modules/java-mongodb