diff --git a/persistence-modules/spring-data-jpa-query-2/README.md b/persistence-modules/spring-data-jpa-query-2/README.md
index a433727a5669..c7ad15e009e2 100644
--- a/persistence-modules/spring-data-jpa-query-2/README.md
+++ b/persistence-modules/spring-data-jpa-query-2/README.md
@@ -7,8 +7,10 @@ This module contains articles about querying data using Spring Data JPA .
- [Hibernate Pagination](https://www.baeldung.com/hibernate-pagination)
- [Sorting with Hibernate](https://www.baeldung.com/hibernate-sort)
- [Stored Procedures with Hibernate](https://www.baeldung.com/stored-procedures-with-hibernate-tutorial)
-- [Eager/Lazy Loading in Hibernate](https://www.baeldung.com/hibernate-lazy-eager-loading)
-- [Auditing with JPA, Hibernate, and Spring Data JPA](https://www.baeldung.com/database-auditing-jpa)
+- [Implement Update-Or-Insert in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-update-or-insert)
+- [The Exists Query in Spring Data](https://www.baeldung.com/spring-data-exists-query)
+- [Spring Data JPA and Named Entity Graphs](https://www.baeldung.com/spring-data-jpa-named-entity-graphs)
+- [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example)
- More articles: [[<-- prev]](../spring-data-jpa-query)[[more -->]](../spring-data-jpa-query-3)
### Eclipse Config
diff --git a/persistence-modules/spring-data-jpa-query-2/pom.xml b/persistence-modules/spring-data-jpa-query-2/pom.xml
index 01c4c0a04a20..9242e8116dda 100644
--- a/persistence-modules/spring-data-jpa-query-2/pom.xml
+++ b/persistence-modules/spring-data-jpa-query-2/pom.xml
@@ -13,17 +13,6 @@
../../parent-boot-3
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
- true
-
-
-
-
@@ -104,6 +93,19 @@
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
9.0.0.M26
1.1
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/CustomPassengerRepository.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/CustomPassengerRepository.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/CustomPassengerRepository.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/CustomPassengerRepository.java
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/Passenger.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/Passenger.java
similarity index 99%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/Passenger.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/Passenger.java
index 3054c3ea17e7..0b86684975c9 100644
--- a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/Passenger.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/Passenger.java
@@ -1,11 +1,12 @@
package com.baeldung.boot.passenger;
+import java.util.Objects;
+
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
-import java.util.Objects;
@Entity
class Passenger {
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/PassengerRepository.java
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java
similarity index 99%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java
index 7125abde4d0e..ac890f42f4e5 100644
--- a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/boot/passenger/PassengerRepositoryImpl.java
@@ -1,10 +1,11 @@
package com.baeldung.boot.passenger;
+import java.util.List;
+
import org.springframework.stereotype.Repository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
-import java.util.List;
@Repository
class PassengerRepositoryImpl implements CustomPassengerRepository {
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/model/Characteristic.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/model/Characteristic.java
similarity index 94%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/model/Characteristic.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/model/Characteristic.java
index 0e3d6a275da4..0e347a30bece 100644
--- a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/model/Characteristic.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/model/Characteristic.java
@@ -1,43 +1,43 @@
-package com.baeldung.entitygraph.model;
-
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-
-@Entity
-public class Characteristic {
-
- @Id
- private Long id;
- private String type;
-
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn
- private Item item;
-
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public Item getItem() {
- return item;
- }
-
- public void setItem(Item item) {
- this.item = item;
- }
-}
+package com.baeldung.entitygraph.model;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+
+@Entity
+public class Characteristic {
+
+ @Id
+ private Long id;
+ private String type;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn
+ private Item item;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public Item getItem() {
+ return item;
+ }
+
+ public void setItem(Item item) {
+ this.item = item;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/model/Item.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/model/Item.java
similarity index 95%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/model/Item.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/model/Item.java
index 51000f60a98b..88f0ea84cee1 100644
--- a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/model/Item.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/model/Item.java
@@ -1,48 +1,48 @@
-package com.baeldung.entitygraph.model;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import jakarta.persistence.Entity;
-import jakarta.persistence.Id;
-import jakarta.persistence.NamedAttributeNode;
-import jakarta.persistence.NamedEntityGraph;
-import jakarta.persistence.OneToMany;
-
-@Entity
-@NamedEntityGraph(name = "Item.characteristics",
- attributeNodes = @NamedAttributeNode("characteristics")
-)
-public class Item {
-
- @Id
- private Long id;
- private String name;
-
- @OneToMany(mappedBy = "item")
- private List characteristics = new ArrayList<>();
-
- 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;
- }
-
- public List getCharacteristics() {
- return characteristics;
- }
-
- public void setCharacteristics(List characteristics) {
- this.characteristics = characteristics;
- }
-}
+package com.baeldung.entitygraph.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.NamedAttributeNode;
+import jakarta.persistence.NamedEntityGraph;
+import jakarta.persistence.OneToMany;
+
+@Entity
+@NamedEntityGraph(name = "Item.characteristics",
+ attributeNodes = @NamedAttributeNode("characteristics")
+)
+public class Item {
+
+ @Id
+ private Long id;
+ private String name;
+
+ @OneToMany(mappedBy = "item")
+ private List characteristics = new ArrayList<>();
+
+ 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;
+ }
+
+ public List getCharacteristics() {
+ return characteristics;
+ }
+
+ public void setCharacteristics(List characteristics) {
+ this.characteristics = characteristics;
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/repository/CharacteristicsRepository.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/repository/CharacteristicsRepository.java
similarity index 96%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/repository/CharacteristicsRepository.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/repository/CharacteristicsRepository.java
index 9f923ab24121..dbb273c23b84 100644
--- a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/repository/CharacteristicsRepository.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/repository/CharacteristicsRepository.java
@@ -1,13 +1,13 @@
-package com.baeldung.entitygraph.repository;
-
-import org.springframework.data.jpa.repository.EntityGraph;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import com.baeldung.entitygraph.model.Characteristic;
-
-public interface CharacteristicsRepository extends JpaRepository {
-
- @EntityGraph(attributePaths = {"item"})
- Characteristic findByType(String type);
-
-}
+package com.baeldung.entitygraph.repository;
+
+import org.springframework.data.jpa.repository.EntityGraph;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.baeldung.entitygraph.model.Characteristic;
+
+public interface CharacteristicsRepository extends JpaRepository {
+
+ @EntityGraph(attributePaths = {"item"})
+ Characteristic findByType(String type);
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/repository/ItemRepository.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/repository/ItemRepository.java
similarity index 97%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/repository/ItemRepository.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/repository/ItemRepository.java
index b2a5f223b3bb..69c9cb358a20 100644
--- a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/entitygraph/repository/ItemRepository.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/entitygraph/repository/ItemRepository.java
@@ -1,13 +1,13 @@
-package com.baeldung.entitygraph.repository;
-
-import org.springframework.data.jpa.repository.EntityGraph;
-import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import com.baeldung.entitygraph.model.Item;
-
-public interface ItemRepository extends JpaRepository- {
-
- @EntityGraph(value = "Item.characteristics", type = EntityGraphType.FETCH)
- Item findByName(String name);
-}
+package com.baeldung.entitygraph.repository;
+
+import org.springframework.data.jpa.repository.EntityGraph;
+import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.baeldung.entitygraph.model.Item;
+
+public interface ItemRepository extends JpaRepository
- {
+
+ @EntityGraph(value = "Item.characteristics", type = EntityGraphType.FETCH)
+ Item findByName(String name);
+}
diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/exists/Application.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/exists/Application.java
new file mode 100644
index 000000000000..5adcc6138e1d
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/exists/Application.java
@@ -0,0 +1,13 @@
+package com.baeldung.exists;
+
+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);
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/exists/Car.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/exists/Car.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/exists/Car.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/exists/Car.java
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/exists/CarRepository.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/exists/CarRepository.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/exists/CarRepository.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/exists/CarRepository.java
diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/CreditCard.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/CreditCard.java
similarity index 82%
rename from persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/CreditCard.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/CreditCard.java
index 3db9f629c82e..5a85e65abdc3 100644
--- a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/CreditCard.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/CreditCard.java
@@ -1,8 +1,11 @@
-package com.baeldung.spring.data.jpa.upsert;
-
-import javax.persistence.*;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
+package com.baeldung.upsert;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.SequenceGenerator;
+import jakarta.persistence.Table;
@Entity
@Table(name = "credit_card")
diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/CreditCardLogic.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/CreditCardLogic.java
similarity index 83%
rename from persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/CreditCardLogic.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/CreditCardLogic.java
index f0e2dc7072d1..7767ad0f4e9a 100644
--- a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/CreditCardLogic.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/CreditCardLogic.java
@@ -1,18 +1,16 @@
-package com.baeldung.spring.data.jpa.upsert;
+package com.baeldung.upsert;
import java.math.BigInteger;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import com.baeldung.upsert.CreditCardRepository;
+
@Service
public class CreditCardLogic {
@@ -36,7 +34,7 @@ public void updateOrInsertUsingCustomLogic(CreditCard creditCard) {
public void updateOrInsertUsingBuiltInFeature(CreditCard creditCard) {
Long id = creditCard.getId();
if (creditCard.getId() == null) {
- BigInteger nextVal = (BigInteger) em.createNativeQuery("SELECT nextval('credit_card_id_seq')")
+ Long nextVal = (Long) em.createNativeQuery("SELECT nextval('credit_card_id_seq')")
.getSingleResult();
id = nextVal.longValue();
}
diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/CreditCardRepository.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/CreditCardRepository.java
similarity index 89%
rename from persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/CreditCardRepository.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/CreditCardRepository.java
index 6b909c619526..e4bb7d1597e4 100644
--- a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/CreditCardRepository.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/CreditCardRepository.java
@@ -1,4 +1,4 @@
-package com.baeldung.spring.data.jpa.upsert;
+package com.baeldung.upsert;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;
diff --git a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/UpsertApplication.java b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/UpsertApplication.java
similarity index 86%
rename from persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/UpsertApplication.java
rename to persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/UpsertApplication.java
index 456b60c8a709..12bdc36bf771 100644
--- a/persistence-modules/spring-data-jpa-query-4/src/main/java/com/baeldung/spring/data/jpa/upsert/UpsertApplication.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/upsert/UpsertApplication.java
@@ -1,4 +1,4 @@
-package com.baeldung.spring.data.jpa.upsert;
+package com.baeldung.upsert;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
similarity index 99%
rename from persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
index 9244fabacca1..eedb3b51ee3e 100644
--- a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/boot/passenger/PassengerRepositoryIntegrationTest.java
@@ -1,5 +1,14 @@
package com.baeldung.boot.passenger;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Optional;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -14,14 +23,6 @@
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
-import java.util.List;
-import java.util.Optional;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.core.IsNot.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
@DataJpaTest(showSql = false)
@RunWith(SpringRunner.class)
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java
similarity index 97%
rename from persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java
index b6bf51ac6585..6768edbc440a 100644
--- a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/entitygraph/EntityGraphIntegrationTest.java
@@ -1,39 +1,41 @@
-package com.baeldung.entitygraph;
-
-import static org.assertj.core.api.Assertions.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.test.context.jdbc.Sql;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import com.baeldung.entitygraph.model.Characteristic;
-import com.baeldung.entitygraph.model.Item;
-import com.baeldung.entitygraph.repository.CharacteristicsRepository;
-import com.baeldung.entitygraph.repository.ItemRepository;
-
-@DataJpaTest(showSql = false)
-@RunWith(SpringRunner.class)
-@Sql(scripts = "/entitygraph-data.sql")
-public class EntityGraphIntegrationTest {
-
- @Autowired
- private ItemRepository itemRepo;
-
- @Autowired
- private CharacteristicsRepository characteristicsRepo;
-
- @Test
- public void givenEntityGraph_whenCalled_shouldRetrunDefinedFields() {
- Item item = itemRepo.findByName("Table");
- assertThat(item.getId()).isEqualTo(1L);
- }
-
- @Test
- public void givenAdhocEntityGraph_whenCalled_shouldRetrunDefinedFields() {
- Characteristic characteristic = characteristicsRepo.findByType("Rigid");
- assertThat(characteristic.getId()).isEqualTo(1L);
- }
-}
+package com.baeldung.entitygraph;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Ignore;
+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.jdbc.Sql;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.entitygraph.model.Characteristic;
+import com.baeldung.entitygraph.model.Item;
+import com.baeldung.entitygraph.repository.CharacteristicsRepository;
+import com.baeldung.entitygraph.repository.ItemRepository;
+
+@Ignore
+@DataJpaTest(showSql = false)
+@RunWith(SpringRunner.class)
+@Sql(scripts = "/entitygraph-data.sql")
+public class EntityGraphIntegrationTest {
+
+ @Autowired
+ private ItemRepository itemRepo;
+
+ @Autowired
+ private CharacteristicsRepository characteristicsRepo;
+
+ @Test
+ public void givenEntityGraph_whenCalled_shouldRetrunDefinedFields() {
+ Item item = itemRepo.findByName("Table");
+ assertThat(item.getId()).isEqualTo(1L);
+ }
+
+ @Test
+ public void givenAdhocEntityGraph_whenCalled_shouldRetrunDefinedFields() {
+ Characteristic characteristic = characteristicsRepo.findByType("Rigid");
+ assertThat(characteristic.getId()).isEqualTo(1L);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java
similarity index 95%
rename from persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java
index 53f22ed0d1e8..32b58e034a54 100644
--- a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/exists/CarRepositoryIntegrationTest.java
@@ -1,25 +1,26 @@
package com.baeldung.exists;
-import com.baeldung.Application;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.ignoreCase;
+
+import java.util.Arrays;
+import java.util.List;
+
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
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.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
-import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
-import java.util.Arrays;
-import java.util.List;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.ignoreCase;
@RunWith(SpringRunner.class)
-@SpringBootTest(classes = {Application.class})
+@SpringBootTest(classes = { Application.class})
public class CarRepositoryIntegrationTest {
@Autowired
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/IntegrationTestSuite.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/IntegrationTestSuite.java
index f5c45a5d6f8c..7d1e25fd335a 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/IntegrationTestSuite.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/IntegrationTestSuite.java
@@ -3,7 +3,6 @@
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
-import com.baeldung.persistence.audit.AuditTestSuite;
import com.baeldung.persistence.hibernate.FooPaginationPersistenceIntegrationTest;
import com.baeldung.persistence.hibernate.FooSortingPersistenceIntegrationTest;
import com.baeldung.persistence.service.FooServiceBasicPersistenceIntegrationTest;
@@ -12,8 +11,7 @@
@RunWith(Suite.class)
@Suite.SuiteClasses({ // @formatter:off
- AuditTestSuite.class
- ,FooServiceBasicPersistenceIntegrationTest.class
+ FooServiceBasicPersistenceIntegrationTest.class
,FooPaginationPersistenceIntegrationTest.class
,FooServicePersistenceIntegrationTest.class
,ParentServicePersistenceIntegrationTest.class
diff --git a/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/upsert/UpdateOrInsertUnitTest.java b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/upsert/UpdateOrInsertUnitTest.java
similarity index 96%
rename from persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/upsert/UpdateOrInsertUnitTest.java
rename to persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/upsert/UpdateOrInsertUnitTest.java
index 89c91c789341..36338cbed43b 100644
--- a/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/upsert/UpdateOrInsertUnitTest.java
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/upsert/UpdateOrInsertUnitTest.java
@@ -1,20 +1,15 @@
-package com.baeldung.spring.data.jpa.upsert;
+package com.baeldung.upsert;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.transaction.annotation.Transactional;
@SpringBootTest(classes = UpsertApplication.class)
public class UpdateOrInsertUnitTest {
diff --git a/persistence-modules/spring-data-jpa-query/src/test/resources/entitygraph-data.sql b/persistence-modules/spring-data-jpa-query-2/src/test/resources/entitygraph-data.sql
similarity index 73%
rename from persistence-modules/spring-data-jpa-query/src/test/resources/entitygraph-data.sql
rename to persistence-modules/spring-data-jpa-query-2/src/test/resources/entitygraph-data.sql
index 73994d88cc61..9863ff1a0ac2 100644
--- a/persistence-modules/spring-data-jpa-query/src/test/resources/entitygraph-data.sql
+++ b/persistence-modules/spring-data-jpa-query-2/src/test/resources/entitygraph-data.sql
@@ -1,5 +1,5 @@
-INSERT INTO "item" ("id", "name") VALUES (1,'Table');
-INSERT INTO "item" ("id", "name") VALUES (2,'Bottle');
+INSERT INTO "ITEM" ("id", "name") VALUES (1,'Table');
+INSERT INTO "ITEM" ("id", "name") VALUES (2,'Bottle');
INSERT INTO "characteristic" ("id", "item_id", "type") VALUES (1,1,'Rigid');
INSERT INTO "characteristic" ("id", "item_id", "type") VALUES (2,1,'Big');
diff --git a/persistence-modules/spring-data-jpa-query-3/README.md b/persistence-modules/spring-data-jpa-query-3/README.md
index daf0fda567e6..8ef620039ca1 100644
--- a/persistence-modules/spring-data-jpa-query-3/README.md
+++ b/persistence-modules/spring-data-jpa-query-3/README.md
@@ -2,10 +2,8 @@
This module contains articles about querying data using Spring Data JPA.
-### Relevant Articles:
-- [Query Entities by Dates and Times with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-query-by-date)
+### Relevant Articles:
- [JPA and Hibernate – Criteria vs. JPQL vs. HQL Query](https://www.baeldung.com/jpql-hql-criteria-query)
-- [Joining Tables With Spring Data JPA Specifications](https://www.baeldung.com/spring-jpa-joining-tables)
- [NonUniqueResultException in Spring Data JPA](https://www.baeldung.com/spring-jpa-non-unique-result-exception)
- [Spring Data Repositories – Collections vs. Stream](https://www.baeldung.com/spring-data-collections-vs-stream)
- [@Query Definitions With SpEL Support in Spring Data JPA](https://www.baeldung.com/spring-data-query-definitions-spel)
diff --git a/persistence-modules/spring-data-jpa-query-4/README.md b/persistence-modules/spring-data-jpa-query-4/README.md
index d2a38abf1647..94e341ff536e 100644
--- a/persistence-modules/spring-data-jpa-query-4/README.md
+++ b/persistence-modules/spring-data-jpa-query-4/README.md
@@ -1,6 +1,5 @@
### Relevant Articles
- [Querying JSONB Columns Using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-querying-jsonb-columns)
-- [Implement Update-Or-Insert in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-update-or-insert)
- [Return Map Instead of List in Spring Data JPA](https://www.baeldung.com/spring-data-return-map-instead-of-list)
- [Converting List to Page Using Spring Data JPA](https://www.baeldung.com/spring-data-jpa-convert-list-page)
- [Get Nextval From Sequence With Spring JPA](https://www.baeldung.com/spring-jpa-sequence-nextval)
diff --git a/persistence-modules/spring-data-jpa-query/README.md b/persistence-modules/spring-data-jpa-query/README.md
index d3958fa1839e..2b3e841fefa4 100644
--- a/persistence-modules/spring-data-jpa-query/README.md
+++ b/persistence-modules/spring-data-jpa-query/README.md
@@ -3,13 +3,15 @@
This module contains articles about querying data using Spring Data JPA
### Relevant Articles:
-- [The Exists Query in Spring Data](https://www.baeldung.com/spring-data-exists-query)
- [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)
-- [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example)
- [JPA Join Types](https://www.baeldung.com/jpa-join-types)
-- [Spring Data JPA and Named Entity Graphs](https://www.baeldung.com/spring-data-jpa-named-entity-graphs)
- [Use Criteria Queries in a Spring Data Application](https://www.baeldung.com/spring-data-criteria-queries)
+- [Query Entities by Dates and Times with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-query-by-date)
+- [Joining Tables With Spring Data JPA Specifications](https://www.baeldung.com/spring-jpa-joining-tables)
+- [Eager/Lazy Loading in Hibernate](https://www.baeldung.com/hibernate-lazy-eager-loading)
+- [Auditing with JPA, Hibernate, and Spring Data JPA](https://www.baeldung.com/database-auditing-jpa)
+
- More articles: [[more -->]](../spring-data-jpa-query-2)
### Eclipse Config
diff --git a/persistence-modules/spring-data-jpa-query/pom.xml b/persistence-modules/spring-data-jpa-query/pom.xml
index 08d5528023e8..12b3607a8112 100644
--- a/persistence-modules/spring-data-jpa-query/pom.xml
+++ b/persistence-modules/spring-data-jpa-query/pom.xml
@@ -18,6 +18,10 @@
org.springframework.boot
spring-boot-starter-data-jpa
+
+ org.springframework.security
+ spring-security-core
+
com.h2database
h2
@@ -36,11 +40,45 @@
spring-oxm
${spring-oxm.version}
+
+ org.hibernate.orm
+ hibernate-core
+ ${hibernate.version}
+
+
+ com.mysql
+ mysql-connector-j
+ ${mysql.version}
+
+
+ org.hibernate.orm
+ hibernate-envers
+ ${hibernate-envers.version}
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+ org.apache.tomcat
+ tomcat-dbcp
+ ${tomcat-dbcp.version}
+
1.4.1
6.1.4
+ 6.5.2.Final
+ 6.5.2.Final
+ 8.2.0
+ 9.0.0.M26
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/datetime/Article.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/datetime/Article.java
new file mode 100644
index 000000000000..c745fee33041
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/datetime/Article.java
@@ -0,0 +1,31 @@
+package com.baeldung.datetime;
+
+import java.util.Date;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.Temporal;
+import jakarta.persistence.TemporalType;
+
+@Entity
+public class Article {
+
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Temporal(TemporalType.DATE)
+ private Date publicationDate;
+
+ @Temporal(TemporalType.TIME)
+ private Date publicationTime;
+
+ @Temporal(TemporalType.TIMESTAMP)
+ private Date creationDateTime;
+
+ public Integer getId() {
+ return id;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/datetime/ArticleRepository.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/datetime/ArticleRepository.java
new file mode 100644
index 000000000000..77c71f9b94d0
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/datetime/ArticleRepository.java
@@ -0,0 +1,25 @@
+package com.baeldung.datetime;
+
+import java.util.Date;
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+
+public interface ArticleRepository extends JpaRepository {
+
+ List findAllByPublicationDate(Date publicationDate);
+
+ List findAllByPublicationTimeBetween(Date publicationTimeStart,
+ Date publicationTimeEnd);
+
+ Article findByPublicationTimeBetween(Date publicationTimeStart,
+ Date publicationTimeEnd);
+
+ @Query("select a from Article a where a.creationDateTime <= :creationDateTime")
+ List findAllWithCreationDateTimeBefore(
+ @Param("creationDateTime") Date creationDateTime);
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/audit/AuditorAwareImpl.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/audit/AuditorAwareImpl.java
new file mode 100644
index 000000000000..5dd12e6841d9
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/audit/AuditorAwareImpl.java
@@ -0,0 +1,18 @@
+package com.baeldung.hibernate.audit;
+
+import java.util.Optional;
+
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+public class AuditorAwareImpl implements AuditorAware {
+
+ @Override
+ public Optional getCurrentAuditor() {
+ return Optional.ofNullable(SecurityContextHolder.getContext())
+ .map(e -> e.getAuthentication())
+ .map(Authentication::getName);
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/audit/PersistenceConfig.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/audit/PersistenceConfig.java
new file mode 100644
index 000000000000..a63235617acc
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/audit/PersistenceConfig.java
@@ -0,0 +1,183 @@
+package com.baeldung.hibernate.audit;
+
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.hibernate5.HibernateTransactionManager;
+import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.JpaVendorAdapter;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import com.baeldung.persistence.dao.IBarAuditableDao;
+import com.baeldung.persistence.dao.IBarDao;
+import com.baeldung.persistence.dao.IFooAuditableDao;
+import com.baeldung.persistence.dao.IFooDao;
+import com.baeldung.persistence.dao.impl.BarAuditableDao;
+import com.baeldung.persistence.dao.impl.BarDao;
+import com.baeldung.persistence.dao.impl.BarJpaDao;
+import com.baeldung.persistence.dao.impl.FooAuditableDao;
+import com.baeldung.persistence.dao.impl.FooDao;
+import com.baeldung.persistence.service.IBarAuditableService;
+import com.baeldung.persistence.service.IBarService;
+import com.baeldung.persistence.service.IFooAuditableService;
+import com.baeldung.persistence.service.IFooService;
+import com.baeldung.persistence.service.impl.BarAuditableService;
+import com.baeldung.persistence.service.impl.BarJpaService;
+import com.baeldung.persistence.service.impl.BarSpringDataJpaService;
+import com.baeldung.persistence.service.impl.FooAuditableService;
+import com.baeldung.persistence.service.impl.FooService;
+import com.google.common.base.Preconditions;
+
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories
+@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
+public class PersistenceConfig {
+
+ @Autowired
+ private Environment env;
+
+ public PersistenceConfig() {
+ super();
+ }
+
+ @Bean("auditorProvider")
+ public AuditorAware auditorProvider() {
+ return new AuditorAwareImpl();
+ }
+
+ @Bean
+ public LocalSessionFactoryBean sessionFactory() {
+ final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
+ sessionFactory.setDataSource(restDataSource());
+ sessionFactory.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
+ sessionFactory.setHibernateProperties(hibernateProperties());
+
+ return sessionFactory;
+ }
+
+ @Bean("jpaEntityManager")
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
+ emf.setDataSource(restDataSource());
+ emf.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
+
+ final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ emf.setJpaVendorAdapter(vendorAdapter);
+ emf.setJpaProperties(hibernateProperties());
+
+ return emf;
+ }
+
+ @Bean
+ public DataSource restDataSource() {
+ final BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
+ dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
+ dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
+ dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
+
+ return dataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager hibernateTransactionManager() {
+ final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
+ transactionManager.setSessionFactory(sessionFactory().getObject());
+ return transactionManager;
+ }
+
+ @Bean
+ public PlatformTransactionManager jpaTransactionManager() {
+ final JpaTransactionManager transactionManager = new JpaTransactionManager();
+ transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
+ return transactionManager;
+ }
+
+ @Bean
+ public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+ return new PersistenceExceptionTranslationPostProcessor();
+ }
+
+ @Bean
+ public IBarService barJpaService() {
+ return new BarJpaService();
+ }
+
+ @Bean
+ public IBarService barSpringDataJpaService() {
+ return new BarSpringDataJpaService();
+ }
+
+ @Bean
+ public IFooService fooHibernateService() {
+ return new FooService();
+ }
+
+ @Bean
+ public IBarAuditableService barHibernateAuditableService() {
+ return new BarAuditableService();
+ }
+
+ @Bean
+ public IFooAuditableService fooHibernateAuditableService() {
+ return new FooAuditableService();
+ }
+
+ @Bean
+ public IBarDao barJpaDao() {
+ return new BarJpaDao();
+ }
+
+ @Bean
+ public IBarDao barHibernateDao() {
+ return new BarDao();
+ }
+
+ @Bean
+ public IBarAuditableDao barHibernateAuditableDao() {
+ return new BarAuditableDao();
+ }
+
+ @Bean
+ public IFooDao fooHibernateDao() {
+ return new FooDao();
+ }
+
+ @Bean
+ public IFooAuditableDao fooHibernateAuditableDao() {
+ return new FooAuditableDao();
+ }
+
+ private final Properties hibernateProperties() {
+ final Properties hibernateProperties = new Properties();
+ hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
+
+ hibernateProperties.setProperty("hibernate.show_sql", "true");
+ // hibernateProperties.setProperty("hibernate.format_sql", "true");
+ hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
+
+ // Envers properties
+ hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix"));
+
+ return hibernateProperties;
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/model/OrderDetail.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/model/OrderDetail.java
similarity index 87%
rename from persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/model/OrderDetail.java
rename to persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/model/OrderDetail.java
index 70349a664df9..d42301ec1d3b 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/model/OrderDetail.java
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/model/OrderDetail.java
@@ -1,9 +1,14 @@
package com.baeldung.hibernate.fetching.model;
-import jakarta.persistence.*;
import java.io.Serializable;
import java.sql.Date;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+
@Entity
@Table(name = "USER_ORDER")
public class OrderDetail implements Serializable {
diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java
similarity index 86%
rename from persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java
rename to persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java
index d273f942a5d5..b36361f2b70d 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java
@@ -1,10 +1,17 @@
package com.baeldung.hibernate.fetching.model;
-import jakarta.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+
@Entity
@Table(name = "USER")
public class UserEager implements Serializable {
diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java
similarity index 86%
rename from persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java
rename to persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java
index 6d18b2517c8a..17f36ed79aa2 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java
@@ -1,10 +1,17 @@
package com.baeldung.hibernate.fetching.model;
-import jakarta.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+
@Entity
@Table(name = "USER")
public class UserLazy implements Serializable {
diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/util/HibernateUtil.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/util/HibernateUtil.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/util/HibernateUtil.java
rename to persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/util/HibernateUtil.java
diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java
similarity index 99%
rename from persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java
rename to persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java
index 35cdd254e3f7..34363a1b8e53 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java
@@ -1,14 +1,15 @@
package com.baeldung.hibernate.fetching.view;
+import java.util.List;
+import java.util.Set;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+
import com.baeldung.hibernate.fetching.model.OrderDetail;
import com.baeldung.hibernate.fetching.model.UserEager;
import com.baeldung.hibernate.fetching.model.UserLazy;
import com.baeldung.hibernate.fetching.util.HibernateUtil;
-import org.hibernate.Session;
-import org.hibernate.Transaction;
-
-import java.util.List;
-import java.util.Set;
public class FetchingAppView {
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IBarAuditableDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IBarAuditableDao.java
new file mode 100644
index 000000000000..182b49359212
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IBarAuditableDao.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.dao;
+
+import com.baeldung.persistence.dao.common.IAuditOperations;
+import com.baeldung.persistence.model.Bar;
+
+public interface IBarAuditableDao extends IBarDao, IAuditOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IBarCrudRepository.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IBarCrudRepository.java
new file mode 100644
index 000000000000..04ce0c2e3fea
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IBarCrudRepository.java
@@ -0,0 +1,11 @@
+package com.baeldung.persistence.dao;
+
+import java.io.Serializable;
+
+import org.springframework.data.repository.CrudRepository;
+
+import com.baeldung.persistence.model.Bar;
+
+public interface IBarCrudRepository extends CrudRepository {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IBarDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IBarDao.java
new file mode 100644
index 000000000000..7896a2a84a87
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IBarDao.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.dao;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Bar;
+
+public interface IBarDao extends IOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IChildDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IChildDao.java
new file mode 100644
index 000000000000..82a1648ba9ee
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IChildDao.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.dao;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Child;
+
+public interface IChildDao extends IOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IFooAuditableDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IFooAuditableDao.java
new file mode 100644
index 000000000000..ddbb68598870
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IFooAuditableDao.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.dao;
+
+import com.baeldung.persistence.dao.common.IAuditOperations;
+import com.baeldung.persistence.model.Foo;
+
+public interface IFooAuditableDao extends IFooDao, IAuditOperations {
+ //
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IFooDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IFooDao.java
new file mode 100644
index 000000000000..a30dffae56d1
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IFooDao.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.dao;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Foo;
+
+public interface IFooDao extends IOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IParentDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IParentDao.java
new file mode 100644
index 000000000000..6a6b0e97587a
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/IParentDao.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.dao;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Parent;
+
+public interface IParentDao extends IOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java
new file mode 100644
index 000000000000..5a6c76a93ad0
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java
@@ -0,0 +1,14 @@
+package com.baeldung.persistence.dao.common;
+
+import java.io.Serializable;
+
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractDao implements IOperations {
+
+ protected Class clazz;
+
+ protected final void setClazz(final Class clazzToSet) {
+ clazz = Preconditions.checkNotNull(clazzToSet);
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateAuditableDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateAuditableDao.java
new file mode 100644
index 000000000000..41184669add6
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateAuditableDao.java
@@ -0,0 +1,37 @@
+package com.baeldung.persistence.dao.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.hibernate.envers.AuditReader;
+import org.hibernate.envers.AuditReaderFactory;
+import org.hibernate.envers.query.AuditQuery;
+
+@SuppressWarnings("unchecked")
+public class AbstractHibernateAuditableDao extends AbstractHibernateDao implements IAuditOperations {
+
+ @Override
+ public List getEntitiesAtRevision(final Number revision) {
+ final AuditReader auditReader = AuditReaderFactory.get(getCurrentSession());
+ final AuditQuery query = auditReader.createQuery().forEntitiesAtRevision(clazz, revision);
+ final List resultList = query.getResultList();
+ return resultList;
+ }
+
+ @Override
+ public List getEntitiesModifiedAtRevision(final Number revision) {
+ final AuditReader auditReader = AuditReaderFactory.get(getCurrentSession());
+ final AuditQuery query = auditReader.createQuery().forEntitiesModifiedAtRevision(clazz, revision);
+ final List resultList = query.getResultList();
+ return resultList;
+ }
+
+ @Override
+ public List getRevisions() {
+ final AuditReader auditReader = AuditReaderFactory.get(getCurrentSession());
+ final AuditQuery query = auditReader.createQuery().forRevisionsOfEntity(clazz, true, true);
+ final List resultList = query.getResultList();
+ return resultList;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java
new file mode 100644
index 000000000000..f3ade67f8025
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java
@@ -0,0 +1,59 @@
+package com.baeldung.persistence.dao.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.common.base.Preconditions;
+
+@SuppressWarnings("unchecked")
+public abstract class AbstractHibernateDao extends AbstractDao implements IOperations {
+
+ @Autowired
+ protected SessionFactory sessionFactory;
+
+ // API
+
+ @Override
+ public T findOne(final long id) {
+ return (T) getCurrentSession().get(clazz, id);
+ }
+
+ @Override
+ public List findAll() {
+ return getCurrentSession().createQuery("from " + clazz.getName()).list();
+ }
+
+ @Override
+ public void create(final T entity) {
+ Preconditions.checkNotNull(entity);
+ getCurrentSession().saveOrUpdate(entity);
+ }
+
+ @Override
+ public T update(final T entity) {
+ Preconditions.checkNotNull(entity);
+ return (T) getCurrentSession().merge(entity);
+ }
+
+ @Override
+ public void delete(final T entity) {
+ Preconditions.checkNotNull(entity);
+ getCurrentSession().delete(entity);
+ }
+
+ @Override
+ public void deleteById(final long entityId) {
+ final T entity = findOne(entityId);
+ Preconditions.checkState(entity != null);
+ delete(entity);
+ }
+
+ protected Session getCurrentSession() {
+ return sessionFactory.getCurrentSession();
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractJpaDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractJpaDao.java
new file mode 100644
index 000000000000..d43ee46844d4
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/AbstractJpaDao.java
@@ -0,0 +1,56 @@
+package com.baeldung.persistence.dao.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.PersistenceContext;
+import jakarta.persistence.TypedQuery;
+import jakarta.persistence.criteria.CriteriaBuilder;
+import jakarta.persistence.criteria.CriteriaQuery;
+import jakarta.persistence.criteria.Root;
+
+public class AbstractJpaDao extends AbstractDao implements IOperations {
+
+ @PersistenceContext(unitName = "jpaEntityManager")
+ private EntityManager em;
+
+ // API
+
+ @Override
+ public T findOne(final long id) {
+ return em.find(clazz, Long.valueOf(id).intValue());
+ }
+
+ @Override
+ public List findAll() {
+ final CriteriaBuilder cb = em.getCriteriaBuilder();
+ final CriteriaQuery cq = cb.createQuery(clazz);
+ final Root rootEntry = cq.from(clazz);
+ final CriteriaQuery all = cq.select(rootEntry);
+ final TypedQuery allQuery = em.createQuery(all);
+ return allQuery.getResultList();
+ }
+
+ @Override
+ public void create(final T entity) {
+ em.persist(entity);
+ }
+
+ @Override
+ public T update(final T entity) {
+ em.merge(entity);
+ return entity;
+ }
+
+ @Override
+ public void delete(final T entity) {
+ em.remove(entity);
+ }
+
+ @Override
+ public void deleteById(final long entityId) {
+ delete(findOne(entityId));
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/GenericHibernateDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/GenericHibernateDao.java
new file mode 100644
index 000000000000..18b16fa03306
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/GenericHibernateDao.java
@@ -0,0 +1,13 @@
+package com.baeldung.persistence.dao.common;
+
+import java.io.Serializable;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@Scope(BeanDefinition.SCOPE_PROTOTYPE)
+public class GenericHibernateDao extends AbstractHibernateDao implements IGenericDao {
+ //
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/IAuditOperations.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/IAuditOperations.java
new file mode 100644
index 000000000000..169d3fed7245
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/IAuditOperations.java
@@ -0,0 +1,14 @@
+package com.baeldung.persistence.dao.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface IAuditOperations {
+
+ List getEntitiesAtRevision(Number revision);
+
+ List getEntitiesModifiedAtRevision(Number revision);
+
+ List getRevisions();
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/IGenericDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/IGenericDao.java
new file mode 100644
index 000000000000..8d8af1839483
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/IGenericDao.java
@@ -0,0 +1,7 @@
+package com.baeldung.persistence.dao.common;
+
+import java.io.Serializable;
+
+public interface IGenericDao extends IOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/IOperations.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/IOperations.java
new file mode 100644
index 000000000000..4ef99221ab8d
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/common/IOperations.java
@@ -0,0 +1,20 @@
+package com.baeldung.persistence.dao.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface IOperations {
+
+ T findOne(final long id);
+
+ List findAll();
+
+ void create(final T entity);
+
+ T update(final T entity);
+
+ void delete(final T entity);
+
+ void deleteById(final long entityId);
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/BarAuditableDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/BarAuditableDao.java
new file mode 100644
index 000000000000..e12b6ae2da60
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/BarAuditableDao.java
@@ -0,0 +1,28 @@
+package com.baeldung.persistence.dao.impl;
+
+import java.util.List;
+
+import com.baeldung.persistence.dao.IBarAuditableDao;
+import com.baeldung.persistence.dao.common.AbstractHibernateAuditableDao;
+import com.baeldung.persistence.model.Bar;
+
+public class BarAuditableDao extends AbstractHibernateAuditableDao implements IBarAuditableDao {
+
+ public BarAuditableDao() {
+ super();
+
+ setClazz(Bar.class);
+ }
+
+ // API
+
+ @Override
+ public List getRevisions() {
+ final List resultList = super.getRevisions();
+ for (final Bar bar : resultList) {
+ bar.getFooSet().size(); // force FooSet initialization
+ }
+ return resultList;
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/BarDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/BarDao.java
new file mode 100644
index 000000000000..e2d1cdf09dc9
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/BarDao.java
@@ -0,0 +1,20 @@
+package com.baeldung.persistence.dao.impl;
+
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.persistence.dao.IBarDao;
+import com.baeldung.persistence.dao.common.AbstractHibernateDao;
+import com.baeldung.persistence.model.Bar;
+
+@Repository
+public class BarDao extends AbstractHibernateDao implements IBarDao {
+
+ public BarDao() {
+ super();
+
+ setClazz(Bar.class);
+ }
+
+ // API
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/BarJpaDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/BarJpaDao.java
new file mode 100644
index 000000000000..997919604e55
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/BarJpaDao.java
@@ -0,0 +1,20 @@
+package com.baeldung.persistence.dao.impl;
+
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.persistence.dao.IBarDao;
+import com.baeldung.persistence.dao.common.AbstractJpaDao;
+import com.baeldung.persistence.model.Bar;
+
+@Repository
+public class BarJpaDao extends AbstractJpaDao implements IBarDao {
+
+ public BarJpaDao() {
+ super();
+
+ setClazz(Bar.class);
+ }
+
+ // API
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/ChildDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/ChildDao.java
new file mode 100644
index 000000000000..73c44cc9beb9
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/ChildDao.java
@@ -0,0 +1,20 @@
+package com.baeldung.persistence.dao.impl;
+
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.persistence.dao.IChildDao;
+import com.baeldung.persistence.dao.common.AbstractHibernateDao;
+import com.baeldung.persistence.model.Child;
+
+@Repository
+public class ChildDao extends AbstractHibernateDao implements IChildDao {
+
+ public ChildDao() {
+ super();
+
+ setClazz(Child.class);
+ }
+
+ // API
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/FooAuditableDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/FooAuditableDao.java
new file mode 100644
index 000000000000..ce8c7cfa66f4
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/FooAuditableDao.java
@@ -0,0 +1,17 @@
+package com.baeldung.persistence.dao.impl;
+
+import com.baeldung.persistence.dao.IFooAuditableDao;
+import com.baeldung.persistence.dao.common.AbstractHibernateAuditableDao;
+import com.baeldung.persistence.model.Foo;
+
+public class FooAuditableDao extends AbstractHibernateAuditableDao implements IFooAuditableDao {
+
+ public FooAuditableDao() {
+ super();
+
+ setClazz(Foo.class);
+ }
+
+ // API
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/FooDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/FooDao.java
new file mode 100644
index 000000000000..21300ff61903
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/FooDao.java
@@ -0,0 +1,20 @@
+package com.baeldung.persistence.dao.impl;
+
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.persistence.dao.IFooDao;
+import com.baeldung.persistence.dao.common.AbstractHibernateDao;
+import com.baeldung.persistence.model.Foo;
+
+@Repository
+public class FooDao extends AbstractHibernateDao implements IFooDao {
+
+ public FooDao() {
+ super();
+
+ setClazz(Foo.class);
+ }
+
+ // API
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/ParentDao.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/ParentDao.java
new file mode 100644
index 000000000000..a25334564f9e
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/dao/impl/ParentDao.java
@@ -0,0 +1,20 @@
+package com.baeldung.persistence.dao.impl;
+
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.persistence.dao.IParentDao;
+import com.baeldung.persistence.dao.common.AbstractHibernateDao;
+import com.baeldung.persistence.model.Parent;
+
+@Repository
+public class ParentDao extends AbstractHibernateDao implements IParentDao {
+
+ public ParentDao() {
+ super();
+
+ setClazz(Parent.class);
+ }
+
+ // API
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Bar.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Bar.java
new file mode 100644
index 000000000000..09746dc753b8
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Bar.java
@@ -0,0 +1,237 @@
+package com.baeldung.persistence.model;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import org.hibernate.annotations.OrderBy;
+import org.hibernate.envers.Audited;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import com.google.common.collect.Sets;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EntityListeners;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.NamedQuery;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.PrePersist;
+import jakarta.persistence.PreRemove;
+import jakarta.persistence.PreUpdate;
+
+@Entity
+@NamedQuery(name = "Bar.findAll", query = "SELECT b FROM Bar b")
+@Audited
+@EntityListeners(AuditingEntityListener.class)
+public class Bar implements Serializable {
+
+ private static final Logger LOGGER = Logger.getLogger(Bar.class.toString());
+
+ public enum OPERATION {
+ INSERT, UPDATE, DELETE;
+ private final String value;
+
+ OPERATION() {
+ value = toString();
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public static OPERATION parse(final String value) {
+ OPERATION operation = null;
+ for (final OPERATION op : OPERATION.values()) {
+ if (op.getValue().equals(value)) {
+ operation = op;
+ break;
+ }
+ }
+ return operation;
+ }
+ };
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @Column(name = "id")
+ private int id;
+
+ @Column(name = "name")
+ private String name;
+
+ @OneToMany(mappedBy = "bar", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ @OrderBy(clause = "name DESC")
+ // @NotAudited
+ private Set fooSet = Sets.newHashSet();
+
+ @Column(name = "operation")
+ private String operation;
+
+ @Column(name = "timestamp")
+ private long timestamp;
+
+ @Column(name = "created_date", updatable = false, nullable = false)
+ @CreatedDate
+ private long createdDate;
+
+ @Column(name = "modified_date")
+ @LastModifiedDate
+ private long modifiedDate;
+
+ @Column(name = "created_by")
+ @CreatedBy
+ private String createdBy;
+
+ @Column(name = "modified_by")
+ @LastModifiedBy
+ private String modifiedBy;
+
+ public Bar() {
+ super();
+ }
+
+ public Bar(final String name) {
+ super();
+ this.name = name;
+ }
+
+ // API
+
+ public Set getFooSet() {
+ return fooSet;
+ }
+
+ public void setFooSet(final Set fooSet) {
+ this.fooSet = fooSet;
+ }
+
+ 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 OPERATION getOperation() {
+ return OPERATION.parse(operation);
+ }
+
+ public void setOperation(final OPERATION operation) {
+ this.operation = operation.getValue();
+ }
+
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(final long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public long getCreatedDate() {
+ return createdDate;
+ }
+
+ public void setCreatedDate(final long createdDate) {
+ this.createdDate = createdDate;
+ }
+
+ public long getModifiedDate() {
+ return modifiedDate;
+ }
+
+ public void setModifiedDate(final long modifiedDate) {
+ this.modifiedDate = modifiedDate;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(final String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public String getModifiedBy() {
+ return modifiedBy;
+ }
+
+ public void setModifiedBy(final String modifiedBy) {
+ this.modifiedBy = modifiedBy;
+ }
+
+ public void setOperation(final String operation) {
+ this.operation = operation;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final Bar other = (Bar) obj;
+ if (name == null) {
+ return other.name == null;
+ } else
+ return name.equals(other.name);
+ }
+
+ @Override
+ public String toString() {
+ return "Bar [name=" + name + "]";
+ }
+
+ @PrePersist
+ public void onPrePersist() {
+ LOGGER.info("@PrePersist");
+ audit(OPERATION.INSERT);
+ }
+
+ @PreUpdate
+ public void onPreUpdate() {
+ LOGGER.info("@PreUpdate");
+ audit(OPERATION.UPDATE);
+ }
+
+ @PreRemove
+ public void onPreRemove() {
+ LOGGER.info("@PreRemove");
+ audit(OPERATION.DELETE);
+ }
+
+ private void audit(final OPERATION operation) {
+ setOperation(operation);
+ setTimestamp((new Date()).getTime());
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Child.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Child.java
new file mode 100644
index 000000000000..9a1f95c01986
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Child.java
@@ -0,0 +1,51 @@
+package com.baeldung.persistence.model;
+
+import java.io.Serializable;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToOne;
+
+@Entity
+public class Child implements Serializable {
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ @OneToOne(mappedBy = "child")
+ private Parent parent;
+
+ public Child() {
+ super();
+ }
+
+ // API
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(final long id) {
+ this.id = id;
+ }
+
+ public Parent getParent() {
+ return parent;
+ }
+
+ public void setParent(final Parent parent) {
+ this.parent = parent;
+ }
+
+ //
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Child [id=").append(id).append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Foo.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Foo.java
new file mode 100644
index 000000000000..e7f7d0fd936a
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Foo.java
@@ -0,0 +1,121 @@
+package com.baeldung.persistence.model;
+
+import java.io.Serializable;
+
+import org.hibernate.envers.Audited;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.NamedNativeQueries;
+import jakarta.persistence.NamedNativeQuery;
+import jakarta.persistence.NamedStoredProcedureQuery;
+import jakarta.persistence.ParameterMode;
+import jakarta.persistence.StoredProcedureParameter;
+
+@NamedNativeQueries({
+ @NamedNativeQuery(name = "callGetAllFoos", query = "CALL GetAllFoos()", resultClass = Foo.class),
+ @NamedNativeQuery(name = "callGetFoosByName", query = "CALL GetFoosByName(:fooName)", resultClass = Foo.class)
+})
+@NamedStoredProcedureQuery(
+ name="GetAllFoos",
+ procedureName="GetAllFoos",
+ resultClasses = { Foo.class }
+ )
+@NamedStoredProcedureQuery(
+ name="GetFoosByName",
+ procedureName="GetFoosByName",
+ resultClasses = { Foo.class },
+ parameters={
+ @StoredProcedureParameter(name="fooName", type=String.class, mode=ParameterMode.IN)
+ }
+ )
+
+@Entity
+@Audited
+// @Proxy(lazy = false)
+public class Foo implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @Column(name = "id")
+ private long id;
+
+ @Column(name = "name")
+ private String name;
+
+ @ManyToOne(targetEntity = Bar.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+ @JoinColumn(name = "BAR_ID")
+ private Bar bar = new Bar();
+
+ public Foo() {
+ super();
+ }
+
+ public Foo(final String name) {
+ super();
+ this.name = name;
+ }
+
+ //
+
+ public Bar getBar() {
+ return bar;
+ }
+
+ public void setBar(final Bar bar) {
+ this.bar = bar;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(final long 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 + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final Foo other = (Foo) obj;
+ if (name == null) {
+ return other.name == null;
+ } else
+ return name.equals(other.name);
+ }
+
+ @Override
+ public String toString() {
+ return "Foo [name=" + name + "]";
+ }
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Parent.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Parent.java
new file mode 100644
index 000000000000..4149a0b883bd
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Parent.java
@@ -0,0 +1,60 @@
+package com.baeldung.persistence.model;
+
+import java.io.Serializable;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.OneToOne;
+
+@Entity
+public class Parent implements Serializable {
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH })
+ @JoinColumn(name = "child_fk")
+ private Child child;
+
+ public Parent() {
+ super();
+ }
+
+ public Parent(final Child child) {
+ super();
+
+ this.child = child;
+ }
+
+ // API
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(final long id) {
+ this.id = id;
+ }
+
+ public Child getChild() {
+ return child;
+ }
+
+ public void setChild(final Child child) {
+ this.child = child;
+ }
+
+ //
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Parent [id=").append(id).append("]");
+ return builder.toString();
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Person.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Person.java
new file mode 100644
index 000000000000..37666399756e
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/model/Person.java
@@ -0,0 +1,31 @@
+package com.baeldung.persistence.model;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+
+@Entity
+public class Person {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ private String 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-query/src/main/java/com/baeldung/persistence/service/IBarAuditableService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IBarAuditableService.java
new file mode 100644
index 000000000000..33e5634d12bd
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IBarAuditableService.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.service;
+
+import com.baeldung.persistence.dao.common.IAuditOperations;
+import com.baeldung.persistence.model.Bar;
+
+public interface IBarAuditableService extends IBarService, IAuditOperations {
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IBarService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IBarService.java
new file mode 100644
index 000000000000..21185b5990dd
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IBarService.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.service;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Bar;
+
+public interface IBarService extends IOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IChildService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IChildService.java
new file mode 100644
index 000000000000..ce648fd991e9
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IChildService.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.service;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Child;
+
+public interface IChildService extends IOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IFooAuditableService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IFooAuditableService.java
new file mode 100644
index 000000000000..b787e7fe9114
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IFooAuditableService.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.service;
+
+import com.baeldung.persistence.dao.common.IAuditOperations;
+import com.baeldung.persistence.model.Foo;
+
+public interface IFooAuditableService extends IFooService, IAuditOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IFooService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IFooService.java
new file mode 100644
index 000000000000..3e8520ed5b1b
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IFooService.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.service;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Foo;
+
+public interface IFooService extends IOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IParentService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IParentService.java
new file mode 100644
index 000000000000..163c0e773f15
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/IParentService.java
@@ -0,0 +1,8 @@
+package com.baeldung.persistence.service;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Parent;
+
+public interface IParentService extends IOperations {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractHibernateAuditableService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractHibernateAuditableService.java
new file mode 100644
index 000000000000..6e6c6d74d1d8
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractHibernateAuditableService.java
@@ -0,0 +1,31 @@
+package com.baeldung.persistence.service.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baeldung.persistence.dao.common.IAuditOperations;
+import com.baeldung.persistence.dao.common.IOperations;
+
+@Transactional(value = "hibernateTransactionManager")
+public abstract class AbstractHibernateAuditableService extends AbstractHibernateService implements IOperations, IAuditOperations {
+
+ @Override
+ public List getEntitiesAtRevision(final Number revision) {
+ return getAuditableDao().getEntitiesAtRevision(revision);
+ }
+
+ @Override
+ public List getEntitiesModifiedAtRevision(final Number revision) {
+ return getAuditableDao().getEntitiesModifiedAtRevision(revision);
+ }
+
+ @Override
+ public List getRevisions() {
+ return getAuditableDao().getRevisions();
+ }
+
+ abstract protected IAuditOperations getAuditableDao();
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractHibernateService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractHibernateService.java
new file mode 100644
index 000000000000..b6a672364edf
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractHibernateService.java
@@ -0,0 +1,43 @@
+package com.baeldung.persistence.service.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baeldung.persistence.dao.common.IOperations;
+
+@Transactional(value = "hibernateTransactionManager")
+public abstract class AbstractHibernateService extends AbstractService implements IOperations {
+
+ @Override
+ public T findOne(final long id) {
+ return super.findOne(id);
+ }
+
+ @Override
+ public List findAll() {
+ return super.findAll();
+ }
+
+ @Override
+ public void create(final T entity) {
+ super.create(entity);
+ }
+
+ @Override
+ public T update(final T entity) {
+ return super.update(entity);
+ }
+
+ @Override
+ public void delete(final T entity) {
+ super.delete(entity);
+ }
+
+ @Override
+ public void deleteById(final long entityId) {
+ super.deleteById(entityId);
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractJpaService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractJpaService.java
new file mode 100644
index 000000000000..4013e6bdddd8
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractJpaService.java
@@ -0,0 +1,43 @@
+package com.baeldung.persistence.service.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baeldung.persistence.dao.common.IOperations;
+
+@Transactional(value = "jpaTransactionManager")
+public abstract class AbstractJpaService extends AbstractService implements IOperations {
+
+ @Override
+ public T findOne(final long id) {
+ return super.findOne(id);
+ }
+
+ @Override
+ public List findAll() {
+ return super.findAll();
+ }
+
+ @Override
+ public void create(final T entity) {
+ super.create(entity);
+ }
+
+ @Override
+ public T update(final T entity) {
+ return super.update(entity);
+ }
+
+ @Override
+ public void delete(final T entity) {
+ super.delete(entity);
+ }
+
+ @Override
+ public void deleteById(final long entityId) {
+ super.deleteById(entityId);
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractService.java
new file mode 100644
index 000000000000..9b001b1fac07
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractService.java
@@ -0,0 +1,42 @@
+package com.baeldung.persistence.service.common;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.baeldung.persistence.dao.common.IOperations;
+
+public abstract class AbstractService implements IOperations {
+
+ @Override
+ public T findOne(final long id) {
+ return getDao().findOne(id);
+ }
+
+ @Override
+ public List findAll() {
+ return getDao().findAll();
+ }
+
+ @Override
+ public void create(final T entity) {
+ getDao().create(entity);
+ }
+
+ @Override
+ public T update(final T entity) {
+ return getDao().update(entity);
+ }
+
+ @Override
+ public void delete(final T entity) {
+ getDao().delete(entity);
+ }
+
+ @Override
+ public void deleteById(final long entityId) {
+ getDao().deleteById(entityId);
+ }
+
+ protected abstract IOperations getDao();
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractSpringDataJpaService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractSpringDataJpaService.java
new file mode 100644
index 000000000000..1b1422615e25
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/common/AbstractSpringDataJpaService.java
@@ -0,0 +1,48 @@
+package com.baeldung.persistence.service.common;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Optional;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baeldung.persistence.dao.common.IOperations;
+import com.google.common.collect.Lists;
+
+@Transactional(value = "jpaTransactionManager")
+public abstract class AbstractSpringDataJpaService implements IOperations {
+
+ @Override
+ public T findOne(final long id) {
+ Optional opt = getDao().findById(Long.valueOf(id));
+ return opt.get();
+ }
+
+ @Override
+ public List findAll() {
+ return Lists.newArrayList(getDao().findAll());
+ }
+
+ @Override
+ public void create(final T entity) {
+ getDao().save(entity);
+ }
+
+ @Override
+ public T update(final T entity) {
+ return getDao().save(entity);
+ }
+
+ @Override
+ public void delete(final T entity) {
+ getDao().delete(entity);
+ }
+
+ @Override
+ public void deleteById(final long entityId) {
+ getDao().deleteById(Long.valueOf(entityId));
+ }
+
+ protected abstract CrudRepository getDao();
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarAuditableService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarAuditableService.java
new file mode 100644
index 000000000000..b5cd28e786bb
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarAuditableService.java
@@ -0,0 +1,42 @@
+package com.baeldung.persistence.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.persistence.dao.IBarAuditableDao;
+import com.baeldung.persistence.dao.IBarDao;
+import com.baeldung.persistence.dao.common.IAuditOperations;
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Bar;
+import com.baeldung.persistence.service.IBarAuditableService;
+import com.baeldung.persistence.service.common.AbstractHibernateAuditableService;
+
+@Service
+public class BarAuditableService extends AbstractHibernateAuditableService implements IBarAuditableService {
+
+ @Autowired
+ @Qualifier("barHibernateDao")
+ private IBarDao dao;
+
+ @Autowired
+ @Qualifier("barHibernateAuditableDao")
+ private IBarAuditableDao auditDao;
+
+ public BarAuditableService() {
+ super();
+ }
+
+ // API
+
+ @Override
+ protected IOperations getDao() {
+ return dao;
+ }
+
+ @Override
+ protected IAuditOperations getAuditableDao() {
+ return auditDao;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarJpaService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarJpaService.java
new file mode 100644
index 000000000000..b9cab19fd6c3
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarJpaService.java
@@ -0,0 +1,31 @@
+package com.baeldung.persistence.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.persistence.dao.IBarDao;
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Bar;
+import com.baeldung.persistence.service.IBarService;
+import com.baeldung.persistence.service.common.AbstractJpaService;
+
+@Service
+public class BarJpaService extends AbstractJpaService implements IBarService {
+
+ @Autowired
+ @Qualifier("barJpaDao")
+ private IBarDao dao;
+
+ public BarJpaService() {
+ super();
+ }
+
+ // API
+
+ @Override
+ protected IOperations getDao() {
+ return dao;
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarService.java
new file mode 100644
index 000000000000..e453f1df555a
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarService.java
@@ -0,0 +1,31 @@
+package com.baeldung.persistence.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.persistence.dao.IBarDao;
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Bar;
+import com.baeldung.persistence.service.IBarService;
+import com.baeldung.persistence.service.common.AbstractHibernateService;
+
+@Service
+public class BarService extends AbstractHibernateService implements IBarService {
+
+ @Autowired
+ @Qualifier("barHibernateDao")
+ private IBarDao dao;
+
+ public BarService() {
+ super();
+ }
+
+ // API
+
+ @Override
+ protected IOperations getDao() {
+ return dao;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarSpringDataJpaService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarSpringDataJpaService.java
new file mode 100644
index 000000000000..a497faf832ab
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/BarSpringDataJpaService.java
@@ -0,0 +1,27 @@
+package com.baeldung.persistence.service.impl;
+
+import java.io.Serializable;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.repository.CrudRepository;
+
+import com.baeldung.persistence.dao.IBarCrudRepository;
+import com.baeldung.persistence.model.Bar;
+import com.baeldung.persistence.service.IBarService;
+import com.baeldung.persistence.service.common.AbstractSpringDataJpaService;
+
+public class BarSpringDataJpaService extends AbstractSpringDataJpaService implements IBarService {
+
+ @Autowired
+ private IBarCrudRepository dao;
+
+ public BarSpringDataJpaService() {
+ super();
+ }
+
+ @Override
+ protected CrudRepository getDao() {
+ return dao;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/ChildService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/ChildService.java
new file mode 100644
index 000000000000..cc09323e9328
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/ChildService.java
@@ -0,0 +1,29 @@
+package com.baeldung.persistence.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.persistence.dao.IChildDao;
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Child;
+import com.baeldung.persistence.service.IChildService;
+import com.baeldung.persistence.service.common.AbstractHibernateService;
+
+@Service
+public class ChildService extends AbstractHibernateService implements IChildService {
+
+ @Autowired
+ private IChildDao dao;
+
+ public ChildService() {
+ super();
+ }
+
+ // API
+
+ @Override
+ protected IOperations getDao() {
+ return dao;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/FooAuditableService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/FooAuditableService.java
new file mode 100644
index 000000000000..e44a60dfa427
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/FooAuditableService.java
@@ -0,0 +1,42 @@
+package com.baeldung.persistence.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.persistence.dao.IFooAuditableDao;
+import com.baeldung.persistence.dao.IFooDao;
+import com.baeldung.persistence.dao.common.IAuditOperations;
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Foo;
+import com.baeldung.persistence.service.IFooAuditableService;
+import com.baeldung.persistence.service.common.AbstractHibernateAuditableService;
+
+@Service
+public class FooAuditableService extends AbstractHibernateAuditableService implements IFooAuditableService {
+
+ @Autowired
+ @Qualifier("fooHibernateDao")
+ private IFooDao dao;
+
+ @Autowired
+ @Qualifier("fooHibernateAuditableDao")
+ private IFooAuditableDao auditDao;
+
+ public FooAuditableService() {
+ super();
+ }
+
+ // API
+
+ @Override
+ protected IOperations getDao() {
+ return dao;
+ }
+
+ @Override
+ protected IAuditOperations getAuditableDao() {
+ return auditDao;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/FooService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/FooService.java
new file mode 100644
index 000000000000..168d50923843
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/FooService.java
@@ -0,0 +1,31 @@
+package com.baeldung.persistence.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.persistence.dao.IFooDao;
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Foo;
+import com.baeldung.persistence.service.IFooService;
+import com.baeldung.persistence.service.common.AbstractHibernateService;
+
+@Service
+public class FooService extends AbstractHibernateService implements IFooService {
+
+ @Autowired
+ @Qualifier("fooHibernateDao")
+ private IFooDao dao;
+
+ public FooService() {
+ super();
+ }
+
+ // API
+
+ @Override
+ protected IOperations getDao() {
+ return dao;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/ParentService.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/ParentService.java
new file mode 100644
index 000000000000..c900b038adc3
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/persistence/service/impl/ParentService.java
@@ -0,0 +1,29 @@
+package com.baeldung.persistence.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.persistence.dao.IParentDao;
+import com.baeldung.persistence.dao.common.IOperations;
+import com.baeldung.persistence.model.Parent;
+import com.baeldung.persistence.service.IParentService;
+import com.baeldung.persistence.service.common.AbstractHibernateService;
+
+@Service
+public class ParentService extends AbstractHibernateService implements IParentService {
+
+ @Autowired
+ private IParentDao dao;
+
+ public ParentService() {
+ super();
+ }
+
+ // API
+
+ @Override
+ protected IOperations getDao() {
+ return dao;
+ }
+
+}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Author.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/Author.java
similarity index 59%
rename from persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Author.java
rename to persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/Author.java
index 70e699ebeba1..06693bf672bb 100644
--- a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Author.java
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/Author.java
@@ -1,9 +1,14 @@
-package com.baeldung.spring.data.jpa.query.specifications.join;
-
-import javax.persistence.*;
+package com.baeldung.specifications.join;
import java.util.List;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToMany;
+
@Entity
public class Author {
@@ -16,7 +21,7 @@ public class Author {
private String lastName;
@OneToMany(cascade = CascadeType.ALL)
- private List books;
+ private List bookAuthorEntities;
public Long getId() {
return id;
@@ -42,16 +47,16 @@ public void setLastName(String lastName) {
this.lastName = lastName;
}
- public List getBooks() {
- return books;
+ public List getBookAuthorEntities() {
+ return bookAuthorEntities;
}
- public void setBooks(List books) {
- this.books = books;
+ public void setBookAuthorEntities(List bookAuthorEntities) {
+ this.bookAuthorEntities = bookAuthorEntities;
}
@Override
public String toString() {
- return "Author{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", books=" + books + '}';
+ return "Author{" + "id=" + id + ", firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", books=" + bookAuthorEntities + '}';
}
}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorSpecifications.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/AuthorSpecifications.java
similarity index 79%
rename from persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorSpecifications.java
rename to persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/AuthorSpecifications.java
index 73d0cd6c018b..e19156394041 100644
--- a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorSpecifications.java
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/AuthorSpecifications.java
@@ -1,8 +1,8 @@
-package com.baeldung.spring.data.jpa.query.specifications.join;
+package com.baeldung.specifications.join;
import org.springframework.data.jpa.domain.Specification;
-import javax.persistence.criteria.*;
+import jakarta.persistence.criteria.Join;
public class AuthorSpecifications {
@@ -16,7 +16,7 @@ public static Specification hasLastName(String name) {
public static Specification hasBookWithTitle(String bookTitle) {
return (root, query, criteriaBuilder) -> {
- Join authorsBook = root.join("books");
+ Join authorsBook = root.join("bookAuthorEntities");
return criteriaBuilder.equal(authorsBook.get("title"), bookTitle);
};
}
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorsRepository.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/AuthorsRepository.java
similarity index 82%
rename from persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorsRepository.java
rename to persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/AuthorsRepository.java
index 67fe86b8b355..abe3e229ac6b 100644
--- a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/AuthorsRepository.java
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/AuthorsRepository.java
@@ -1,4 +1,4 @@
-package com.baeldung.spring.data.jpa.query.specifications.join;
+package com.baeldung.specifications.join;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
diff --git a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Book.java b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/BookAuthorEntity.java
similarity index 68%
rename from persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Book.java
rename to persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/BookAuthorEntity.java
index 3d658ca1071b..98d4b7b1fb49 100644
--- a/persistence-modules/spring-data-jpa-query-3/src/main/java/com/baeldung/spring/data/jpa/query/specifications/join/Book.java
+++ b/persistence-modules/spring-data-jpa-query/src/main/java/com/baeldung/specifications/join/BookAuthorEntity.java
@@ -1,12 +1,12 @@
-package com.baeldung.spring.data.jpa.query.specifications.join;
+package com.baeldung.specifications.join;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
@Entity
-public class Book {
+public class BookAuthorEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/resources/fetching.cfg.xml b/persistence-modules/spring-data-jpa-query/src/main/resources/fetching.cfg.xml
similarity index 100%
rename from persistence-modules/spring-data-jpa-query-2/src/main/resources/fetching.cfg.xml
rename to persistence-modules/spring-data-jpa-query/src/main/resources/fetching.cfg.xml
diff --git a/persistence-modules/spring-data-jpa-query-2/src/main/resources/fetchingLazy.cfg.xml b/persistence-modules/spring-data-jpa-query/src/main/resources/fetchingLazy.cfg.xml
similarity index 100%
rename from persistence-modules/spring-data-jpa-query-2/src/main/resources/fetchingLazy.cfg.xml
rename to persistence-modules/spring-data-jpa-query/src/main/resources/fetchingLazy.cfg.xml
diff --git a/persistence-modules/spring-data-jpa-query/src/main/resources/import_entities.sql b/persistence-modules/spring-data-jpa-query/src/main/resources/import_entities.sql
new file mode 100644
index 000000000000..fd33d080414f
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/main/resources/import_entities.sql
@@ -0,0 +1,8 @@
+INSERT INTO "article" ("id", "publication_date", "publication_time", "creation_date_time")
+VALUES (1, PARSEDATETIME('01/01/2018', 'dd/MM/yyyy'), PARSEDATETIME('15:00', 'HH:mm'), PARSEDATETIME('31/12/2017 07:30', 'dd/MM/yyyy HH:mm'));
+
+INSERT INTO "article" ("id", "publication_date", "publication_time", "creation_date_time")
+VALUES (2, PARSEDATETIME('01/01/2018', 'dd/MM/yyyy'), PARSEDATETIME('15:30', 'HH:mm'), PARSEDATETIME('15/12/2017 08:00', 'dd/MM/yyyy HH:mm'));
+
+INSERT INTO "article" ("id", "publication_date", "publication_time", "creation_date_time")
+VALUES (3, PARSEDATETIME('15/12/2017', 'dd/MM/yyyy'), PARSEDATETIME('16:00', 'HH:mm'), PARSEDATETIME('01/12/2017 13:45', 'dd/MM/yyyy HH:mm'));
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/datetime/ArticleRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/datetime/ArticleRepositoryIntegrationTest.java
similarity index 92%
rename from persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/datetime/ArticleRepositoryIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/datetime/ArticleRepositoryIntegrationTest.java
index b97fbc5275fc..c12a4c46c19f 100644
--- a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/datetime/ArticleRepositoryIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/datetime/ArticleRepositoryIntegrationTest.java
@@ -1,4 +1,11 @@
-package com.baeldung.spring.data.jpa.query.datetime;
+package com.baeldung.datetime;
+
+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 org.junit.Test;
import org.junit.runner.RunWith;
@@ -6,15 +13,6 @@
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.junit4.SpringRunner;
-import com.baeldung.spring.data.jpa.query.datetime.Article;
-import com.baeldung.spring.data.jpa.query.datetime.ArticleRepository;
-
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
@RunWith(SpringRunner.class)
@DataJpaTest(properties="spring.sql.init.data-locations=classpath:import_entities.sql", showSql = false)
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/hibernate/fetching/HibernateFetchingIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/hibernate/fetching/HibernateFetchingIntegrationTest.java
similarity index 99%
rename from persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/hibernate/fetching/HibernateFetchingIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/hibernate/fetching/HibernateFetchingIntegrationTest.java
index e90207a1706c..54bdb2a4b1e8 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/hibernate/fetching/HibernateFetchingIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/hibernate/fetching/HibernateFetchingIntegrationTest.java
@@ -1,15 +1,16 @@
package com.baeldung.hibernate.fetching;
-import com.baeldung.hibernate.fetching.model.OrderDetail;
-import com.baeldung.hibernate.fetching.view.FetchingAppView;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Set;
+
import org.hibernate.Hibernate;
import org.junit.Before;
import org.junit.Test;
-import java.util.Set;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import com.baeldung.hibernate.fetching.model.OrderDetail;
+import com.baeldung.hibernate.fetching.view.FetchingAppView;
public class HibernateFetchingIntegrationTest {
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/IntegrationTestSuite.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/IntegrationTestSuite.java
new file mode 100644
index 000000000000..7b62c4676988
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/IntegrationTestSuite.java
@@ -0,0 +1,14 @@
+package com.baeldung.persistence;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+import com.baeldung.persistence.audit.AuditTestSuite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({ // @formatter:off
+ AuditTestSuite.class
+}) // @formatter:on
+public class IntegrationTestSuite {
+ //
+}
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/AuditTestSuite.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/AuditTestSuite.java
similarity index 100%
rename from persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/AuditTestSuite.java
rename to persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/AuditTestSuite.java
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java
similarity index 98%
rename from persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java
index 09d44956b3ef..f450e144d4a9 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java
@@ -1,10 +1,10 @@
package com.baeldung.persistence.audit;
-import com.baeldung.persistence.model.Bar;
-import com.baeldung.persistence.model.Foo;
-import com.baeldung.persistence.service.IBarAuditableService;
-import com.baeldung.persistence.service.IFooAuditableService;
-import com.baeldung.spring.config.PersistenceTestConfig;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
@@ -20,10 +20,11 @@
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import com.baeldung.persistence.model.Bar;
+import com.baeldung.persistence.model.Foo;
+import com.baeldung.persistence.service.IBarAuditableService;
+import com.baeldung.persistence.service.IFooAuditableService;
+import com.baeldung.persistence.config.PersistenceTestConfig;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class)
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java
similarity index 98%
rename from persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java
index d9ab75af2c6d..c671688431f6 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java
@@ -4,9 +4,6 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import jakarta.persistence.EntityManager;
-import jakarta.persistence.EntityManagerFactory;
-
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -24,7 +21,10 @@
import com.baeldung.persistence.model.Bar;
import com.baeldung.persistence.model.Bar.OPERATION;
import com.baeldung.persistence.service.IBarService;
-import com.baeldung.spring.config.PersistenceTestConfig;
+import com.baeldung.persistence.config.PersistenceTestConfig;
+
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.EntityManagerFactory;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class)
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java
similarity index 97%
rename from persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java
index 0d22562a938b..6d82da643c3f 100644
--- a/persistence-modules/spring-data-jpa-query-2/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java
@@ -3,9 +3,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import jakarta.persistence.EntityManager;
-import jakarta.persistence.EntityManagerFactory;
-
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -23,7 +20,10 @@
import com.baeldung.persistence.model.Bar;
import com.baeldung.persistence.service.IBarService;
-import com.baeldung.spring.config.PersistenceTestConfig;
+import com.baeldung.persistence.config.PersistenceTestConfig;
+
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.EntityManagerFactory;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class)
diff --git a/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/config/PersistenceTestConfig.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/config/PersistenceTestConfig.java
new file mode 100644
index 000000000000..a1cd55028e51
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/persistence/config/PersistenceTestConfig.java
@@ -0,0 +1,179 @@
+package com.baeldung.persistence.config;
+
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.hibernate5.HibernateTransactionManager;
+import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.JpaVendorAdapter;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import com.baeldung.persistence.dao.IBarAuditableDao;
+import com.baeldung.persistence.dao.IBarDao;
+import com.baeldung.persistence.dao.IFooAuditableDao;
+import com.baeldung.persistence.dao.IFooDao;
+import com.baeldung.persistence.dao.impl.BarAuditableDao;
+import com.baeldung.persistence.dao.impl.BarDao;
+import com.baeldung.persistence.dao.impl.BarJpaDao;
+import com.baeldung.persistence.dao.impl.FooAuditableDao;
+import com.baeldung.persistence.dao.impl.FooDao;
+import com.baeldung.persistence.service.IBarAuditableService;
+import com.baeldung.persistence.service.IBarService;
+import com.baeldung.persistence.service.IFooAuditableService;
+import com.baeldung.persistence.service.IFooService;
+import com.baeldung.persistence.service.impl.BarAuditableService;
+import com.baeldung.persistence.service.impl.BarJpaService;
+import com.baeldung.persistence.service.impl.BarSpringDataJpaService;
+import com.baeldung.persistence.service.impl.FooAuditableService;
+import com.baeldung.persistence.service.impl.FooService;
+import com.google.common.base.Preconditions;
+
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(basePackages = { "com.baeldung.persistence" }, transactionManagerRef = "jpaTransactionManager", entityManagerFactoryRef = "jpaEntityManager")
+@EnableJpaAuditing
+@PropertySource({ "classpath:persistence-h2.properties" })
+@ComponentScan({ "com.baeldung.persistence" })
+public class PersistenceTestConfig {
+
+ @Autowired
+ private Environment env;
+
+ public PersistenceTestConfig() {
+ super();
+ }
+
+ @Bean
+ public LocalSessionFactoryBean sessionFactory() {
+ final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
+ sessionFactory.setDataSource(restDataSource());
+ sessionFactory.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
+ sessionFactory.setHibernateProperties(hibernateProperties());
+
+ return sessionFactory;
+ }
+
+ @Bean("jpaEntityManager")
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
+ emf.setDataSource(restDataSource());
+ emf.setPackagesToScan(new String[] { "com.baeldung.persistence.model" });
+
+ final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ emf.setJpaVendorAdapter(vendorAdapter);
+ emf.setJpaProperties(hibernateProperties());
+
+ return emf;
+ }
+
+ @Bean
+ public DataSource restDataSource() {
+ final BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
+ dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
+ dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
+ dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
+
+ return dataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager hibernateTransactionManager() {
+ final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
+ transactionManager.setSessionFactory(sessionFactory().getObject());
+ return transactionManager;
+ }
+
+ @Bean
+ public PlatformTransactionManager jpaTransactionManager() {
+ final JpaTransactionManager transactionManager = new JpaTransactionManager();
+ transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
+ return transactionManager;
+ }
+
+ @Bean
+ public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+ return new PersistenceExceptionTranslationPostProcessor();
+ }
+
+ @Bean
+ public IBarService barJpaService() {
+ return new BarJpaService();
+ }
+
+ @Bean
+ public IBarService barSpringDataJpaService() {
+ return new BarSpringDataJpaService();
+ }
+
+ @Bean
+ public IFooService fooHibernateService() {
+ return new FooService();
+ }
+
+ @Bean
+ public IBarAuditableService barHibernateAuditableService() {
+ return new BarAuditableService();
+ }
+
+ @Bean
+ public IFooAuditableService fooHibernateAuditableService() {
+ return new FooAuditableService();
+ }
+
+ @Bean
+ public IBarDao barJpaDao() {
+ return new BarJpaDao();
+ }
+
+ @Bean
+ public IBarDao barHibernateDao() {
+ return new BarDao();
+ }
+
+ @Bean
+ public IBarAuditableDao barHibernateAuditableDao() {
+ return new BarAuditableDao();
+ }
+
+ @Bean
+ public IFooDao fooHibernateDao() {
+ return new FooDao();
+ }
+
+ @Bean
+ public IFooAuditableDao fooHibernateAuditableDao() {
+ return new FooAuditableDao();
+ }
+
+ private final Properties hibernateProperties() {
+ final Properties hibernateProperties = new Properties();
+ hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
+
+ hibernateProperties.setProperty("hibernate.show_sql", "false");
+ // hibernateProperties.setProperty("hibernate.format_sql", "true");
+ // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
+
+ // Envers properties
+ hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix"));
+
+ return hibernateProperties;
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/specifications/join/SpecificationsJoinIntegrationTest.java b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/specifications/join/SpecificationsJoinIntegrationTest.java
similarity index 75%
rename from persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/specifications/join/SpecificationsJoinIntegrationTest.java
rename to persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/specifications/join/SpecificationsJoinIntegrationTest.java
index 27db09d11c3e..49509351514c 100644
--- a/persistence-modules/spring-data-jpa-query-3/src/test/java/com/baeldung/spring/data/jpa/query/specifications/join/SpecificationsJoinIntegrationTest.java
+++ b/persistence-modules/spring-data-jpa-query/src/test/java/com/baeldung/specifications/join/SpecificationsJoinIntegrationTest.java
@@ -1,4 +1,12 @@
-package com.baeldung.spring.data.jpa.query.specifications.join;
+package com.baeldung.specifications.join;
+
+import static com.baeldung.specifications.join.AuthorSpecifications.hasBookWithTitle;
+import static com.baeldung.specifications.join.AuthorSpecifications.hasFirstNameLike;
+import static com.baeldung.specifications.join.AuthorSpecifications.hasLastName;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
@@ -8,12 +16,6 @@
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.junit4.SpringRunner;
-import java.util.Arrays;
-import java.util.List;
-
-import static com.baeldung.spring.data.jpa.query.specifications.join.AuthorSpecifications.*;
-import static org.assertj.core.api.Assertions.assertThat;
-
@RunWith(SpringRunner.class)
@DataJpaTest
public class SpecificationsJoinIntegrationTest {
@@ -69,12 +71,12 @@ private void saveTestData() {
uncleBob.setFirstName("Robert");
uncleBob.setLastName("Martin");
- Book book1 = new Book();
- book1.setTitle("Clean Code");
- Book book2 = new Book();
- book2.setTitle("Clean Architecture");
+ BookAuthorEntity bookAuthorEntity1 = new BookAuthorEntity();
+ bookAuthorEntity1.setTitle("Clean Code");
+ BookAuthorEntity bookAuthorEntity2 = new BookAuthorEntity();
+ bookAuthorEntity2.setTitle("Clean Architecture");
- uncleBob.setBooks(Arrays.asList(book1, book2));
+ uncleBob.setBookAuthorEntities(Arrays.asList(bookAuthorEntity1, bookAuthorEntity2));
repository.save(uncleBob);
}
}
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetching.cfg.xml b/persistence-modules/spring-data-jpa-query/src/test/resources/fetching.cfg.xml
similarity index 100%
rename from persistence-modules/spring-data-jpa-query-2/src/test/resources/fetching.cfg.xml
rename to persistence-modules/spring-data-jpa-query/src/test/resources/fetching.cfg.xml
diff --git a/persistence-modules/spring-data-jpa-query-2/src/test/resources/fetchingLazy.cfg.xml b/persistence-modules/spring-data-jpa-query/src/test/resources/fetchingLazy.cfg.xml
similarity index 100%
rename from persistence-modules/spring-data-jpa-query-2/src/test/resources/fetchingLazy.cfg.xml
rename to persistence-modules/spring-data-jpa-query/src/test/resources/fetchingLazy.cfg.xml
diff --git a/persistence-modules/spring-data-jpa-query/src/test/resources/persistence-h2.properties b/persistence-modules/spring-data-jpa-query/src/test/resources/persistence-h2.properties
new file mode 100644
index 000000000000..911619193bf8
--- /dev/null
+++ b/persistence-modules/spring-data-jpa-query/src/test/resources/persistence-h2.properties
@@ -0,0 +1,13 @@
+# jdbc.X
+jdbc.driverClassName=org.h2.Driver
+jdbc.url=jdbc:h2:mem:test
+jdbc.user=sa
+jdbc.pass=
+
+# hibernate.X
+hibernate.dialect=org.hibernate.dialect.H2Dialect
+hibernate.show_sql=false
+hibernate.hbm2ddl.auto=create-drop
+
+# envers.X
+envers.audit_table_suffix=_audit_log