diff --git a/data/demo.mv.db b/data/demo.mv.db
index 9d7ff71..7ee7076 100644
Binary files a/data/demo.mv.db and b/data/demo.mv.db differ
diff --git a/pom.xml b/pom.xml
index 9466ccb..48b6579 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,6 +3,12 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.1
+
+
dev.struchkov.example.hibernate
hibernate-multiple-bag-fetch-exception
@@ -15,9 +21,8 @@
- org.hibernate.orm
- hibernate-core
- 6.1.0.Final
+ org.springframework.boot
+ spring-boot-starter-data-jpa
com.h2database
diff --git a/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/FixProblem.java b/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/FixProblem.java
deleted file mode 100644
index 2c8e14a..0000000
--- a/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/FixProblem.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package dev.struchkov.example.hibernate.nbfe.fix;
-
-import dev.struchkov.example.hibernate.nbfe.fix.domain.Post;
-import jakarta.persistence.EntityManager;
-import jakarta.persistence.EntityManagerFactory;
-import jakarta.persistence.Persistence;
-import org.hibernate.annotations.QueryHints;
-
-import java.util.List;
-
-public class FixProblem {
-
- public static void main(String[] args) {
- final EntityManagerFactory emf = Persistence.createEntityManagerFactory("Blog");
- final EntityManager entityManager = emf.createEntityManager();
-
- final long startTime = System.currentTimeMillis();
- List posts = entityManager.createQuery("""
- select distinct p
- from Post p
- left join fetch p.comments
- where p.id between :minId and :maxId""", Post.class)
- .setParameter("minId", 1L)
- .setParameter("maxId", 50L)
- .getResultList();
-
- posts = entityManager.createQuery("""
- select distinct p
- from Post p
- left join fetch p.tags t
- where p in :posts""", Post.class)
- .setParameter("posts", posts)
- .getResultList();
-
- final long finishTime = System.currentTimeMillis();
- System.out.println("Performance: " + (finishTime - startTime));
- }
-
-}
diff --git a/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/domain/Tag.java b/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/domain/Tag.java
deleted file mode 100644
index d86837f..0000000
--- a/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/domain/Tag.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package dev.struchkov.example.hibernate.nbfe.fix.domain;
-
-import jakarta.persistence.Entity;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.Id;
-import lombok.Getter;
-import lombok.Setter;
-
-@Entity
-@Getter
-@Setter
-public class Tag {
-
- @Id
- @GeneratedValue
- private Long id;
-
- private String name;
-
-}
diff --git a/src/main/java/dev/struchkov/example/spring/nbfe/SpringApp.java b/src/main/java/dev/struchkov/example/spring/nbfe/SpringApp.java
new file mode 100644
index 0000000..fe41f58
--- /dev/null
+++ b/src/main/java/dev/struchkov/example/spring/nbfe/SpringApp.java
@@ -0,0 +1,31 @@
+package dev.struchkov.example.spring.nbfe;
+
+import dev.struchkov.example.spring.nbfe.domain.Post;
+import dev.struchkov.example.spring.nbfe.repository.PostRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.event.ContextStartedEvent;
+import org.springframework.context.event.EventListener;
+
+import java.util.List;
+
+@SpringBootApplication
+@RequiredArgsConstructor
+public class SpringApp {
+
+ private final PostRepository postRepository;
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringApp.class, args);
+ }
+
+ @EventListener
+ public void run(ContextStartedEvent event) {
+ final long start = System.currentTimeMillis();
+ final List allWithCommentsAndTags = postRepository.findAllWithCommentsAndTags(1, 50);
+ final long finish = System.currentTimeMillis();
+ System.out.println(finish - start);
+ }
+
+}
diff --git a/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/domain/Post.java b/src/main/java/dev/struchkov/example/spring/nbfe/domain/Post.java
similarity index 72%
rename from src/main/java/dev/struchkov/example/hibernate/nbfe/fix/domain/Post.java
rename to src/main/java/dev/struchkov/example/spring/nbfe/domain/Post.java
index a165d72..304d8b5 100644
--- a/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/domain/Post.java
+++ b/src/main/java/dev/struchkov/example/spring/nbfe/domain/Post.java
@@ -1,16 +1,16 @@
-package dev.struchkov.example.hibernate.nbfe.fix.domain;
+package dev.struchkov.example.spring.nbfe.domain;
-import jakarta.persistence.CascadeType;
-import jakarta.persistence.Entity;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.JoinTable;
-import jakarta.persistence.ManyToMany;
-import jakarta.persistence.OneToMany;
import lombok.Getter;
import lombok.Setter;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/domain/PostComment.java b/src/main/java/dev/struchkov/example/spring/nbfe/domain/PostComment.java
similarity index 51%
rename from src/main/java/dev/struchkov/example/hibernate/nbfe/fix/domain/PostComment.java
rename to src/main/java/dev/struchkov/example/spring/nbfe/domain/PostComment.java
index 41abda9..0325bef 100644
--- a/src/main/java/dev/struchkov/example/hibernate/nbfe/fix/domain/PostComment.java
+++ b/src/main/java/dev/struchkov/example/spring/nbfe/domain/PostComment.java
@@ -1,12 +1,13 @@
-package dev.struchkov.example.hibernate.nbfe.fix.domain;
+package dev.struchkov.example.spring.nbfe.domain;
-import jakarta.persistence.Entity;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.Id;
-import jakarta.persistence.ManyToOne;
import lombok.Getter;
import lombok.Setter;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
@Entity
@Getter
@Setter
diff --git a/src/main/java/dev/struchkov/example/spring/nbfe/domain/Tag.java b/src/main/java/dev/struchkov/example/spring/nbfe/domain/Tag.java
new file mode 100644
index 0000000..b31ee5b
--- /dev/null
+++ b/src/main/java/dev/struchkov/example/spring/nbfe/domain/Tag.java
@@ -0,0 +1,22 @@
+package dev.struchkov.example.spring.nbfe.domain;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Getter
+@Setter
+public class Tag {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ private String name;
+
+}
diff --git a/src/main/java/dev/struchkov/example/spring/nbfe/repository/PostRepository.java b/src/main/java/dev/struchkov/example/spring/nbfe/repository/PostRepository.java
new file mode 100644
index 0000000..0c354b3
--- /dev/null
+++ b/src/main/java/dev/struchkov/example/spring/nbfe/repository/PostRepository.java
@@ -0,0 +1,24 @@
+package dev.struchkov.example.spring.nbfe.repository;
+
+import dev.struchkov.example.spring.nbfe.domain.Post;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface PostRepository extends JpaRepository {
+
+ @Query("""
+ select distinct p
+ from Post p
+ left join fetch p.comments
+ left join fetch p.tags
+ where p.id between :minId and :maxId
+ """)
+ List findAllWithCommentsAndTags(
+ @Param("minId") long minId,
+ @Param("maxId") long maxId
+ );
+
+}
diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml
deleted file mode 100644
index 71147ad..0000000
--- a/src/main/resources/META-INF/persistence.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- dev.struchkov.example.hibernate.nbfe.fix.domain.Post
- dev.struchkov.example.hibernate.nbfe.fix.domain.PostComment
- dev.struchkov.example.hibernate.nbfe.fix.domain.Tag
- true
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..010f693
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,6 @@
+spring:
+ jpa:
+ show-sql: true
+ properties:
+ hibernate:
+ format_sql: true