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