From 27c53fd6deea979b598020b02e91423650f79cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20G=C5=82=C3=B3wka?= Date: Tue, 25 May 2021 21:48:22 +0200 Subject: [PATCH] BAEL-4887: fetching multiple entities in JPA query (#10803) --- .../jpa/returnmultipleentities/Channel.java | 43 ++++++++++ .../ReportRepository.java | 23 +++++ .../returnmultipleentities/Subscription.java | 41 +++++++++ .../jpa/returnmultipleentities/User.java | 29 +++++++ .../main/resources/META-INF/persistence.xml | 20 +++++ ...ReturnMultipleEntitiesIntegrationTest.java | 84 +++++++++++++++++++ 6 files changed, 240 insertions(+) create mode 100644 persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/Channel.java create mode 100644 persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/ReportRepository.java create mode 100644 persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/Subscription.java create mode 100644 persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/User.java create mode 100644 persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/returnmultipleentities/ReturnMultipleEntitiesIntegrationTest.java diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/Channel.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/Channel.java new file mode 100644 index 0000000000..7f60dd8de4 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/Channel.java @@ -0,0 +1,43 @@ +package com.baeldung.jpa.returnmultipleentities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.util.Objects; + +@Entity +public class Channel { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String code; + + private Long subscriptionId; + + public void setCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public void setSubscriptionId(Long subscriptionId) { + this.subscriptionId = subscriptionId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Channel channel = (Channel) o; + return Objects.equals(id, channel.id) && Objects.equals(code, channel.code) && Objects.equals(subscriptionId, channel.subscriptionId); + } + + @Override + public int hashCode() { + return Objects.hash(id, code, subscriptionId); + } +} diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/ReportRepository.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/ReportRepository.java new file mode 100644 index 0000000000..ae574de7d5 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/ReportRepository.java @@ -0,0 +1,23 @@ +package com.baeldung.jpa.returnmultipleentities; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import java.util.List; + +public class ReportRepository { + private final EntityManagerFactory emf; + + public ReportRepository() { + emf = Persistence.createEntityManagerFactory("jpa-h2-return-multiple-entities"); + } + + public List find(String email) { + EntityManager entityManager = emf.createEntityManager(); + Query query = entityManager.createQuery("SELECT c, s, u FROM Channel c, Subscription s, User u WHERE c.subscriptionId = s.id AND s.id = u.subscriptionId AND u.email=:email"); + query.setParameter("email", email); + + return query.getResultList(); + } +} diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/Subscription.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/Subscription.java new file mode 100644 index 0000000000..91510ebb9f --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/Subscription.java @@ -0,0 +1,41 @@ +package com.baeldung.jpa.returnmultipleentities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.util.Objects; + +@Entity +public class Subscription { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String code; + + public void setCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public Long getId() { + return id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Subscription subscription = (Subscription) o; + return Objects.equals(id, subscription.id) && Objects.equals(code, subscription.code); + } + + @Override + public int hashCode() { + return Objects.hash(id, code); + } +} diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/User.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/User.java new file mode 100644 index 0000000000..35d546b57d --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/returnmultipleentities/User.java @@ -0,0 +1,29 @@ +package com.baeldung.jpa.returnmultipleentities; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class User { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String email; + + private Long subscriptionId; + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setSubscriptionId(Long subscriptionId) { + this.subscriptionId = subscriptionId; + } +} diff --git a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml index bc41f35c01..666fc1500a 100644 --- a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml @@ -113,4 +113,24 @@ + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.returnmultipleentities.Channel + com.baeldung.jpa.returnmultipleentities.Subscription + com.baeldung.jpa.returnmultipleentities.User + com.baeldung.jpa.returnmultipleentities.ReportRepository + true + + + + + + + + + + + + + diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/returnmultipleentities/ReturnMultipleEntitiesIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/returnmultipleentities/ReturnMultipleEntitiesIntegrationTest.java new file mode 100644 index 0000000000..eb71060f22 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/returnmultipleentities/ReturnMultipleEntitiesIntegrationTest.java @@ -0,0 +1,84 @@ +package com.baeldung.jpa.returnmultipleentities; + +import org.junit.Before; +import org.junit.Test; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class ReturnMultipleEntitiesIntegrationTest { + private static EntityManagerFactory factory; + private static EntityManager entityManager; + private ReportRepository reportRepository; + + @Before + public void setup() { + factory = Persistence.createEntityManagerFactory("jpa-h2-return-multiple-entities"); + entityManager = factory.createEntityManager(); + reportRepository = new ReportRepository(); + populateH2DB(); + } + + @Test + public void whenQueryingForMultipleEntitiesInOneQuery_thenJPAReturnsMultipleEntitiesInCorrectOrder() { + List reportDetails = reportRepository.find("user1@gmail.com"); + + assertEquals(2, reportDetails.size()); + + for (Object[] reportDetail : reportDetails) { + assertEquals(3, reportDetail.length); + + Channel channel = (Channel) reportDetail[0]; + Subscription subscription = (Subscription) reportDetail[1]; + User user = (User) reportDetail[2]; + + assertEquals("single", subscription.getCode()); + assertEquals("user1@gmail.com", user.getEmail()); + if (!("eurosport".equals(channel.getCode()) || "hbo".equals(channel.getCode()))) { + fail(); + } + } + } + + private static void populateH2DB() { + entityManager.getTransaction().begin(); + + Subscription single = new Subscription(); + single.setCode("single"); + + Subscription family = new Subscription(); + family.setCode("family"); + + entityManager.persist(single); + entityManager.persist(family); + + Channel bbc = new Channel(); + bbc.setCode("bbc"); + bbc.setSubscriptionId(family.getId()); + + Channel eurosport = new Channel(); + eurosport.setCode("eurosport"); + eurosport.setSubscriptionId(single.getId()); + + Channel hbo = new Channel(); + hbo.setCode("hbo"); + hbo.setSubscriptionId(single.getId()); + + entityManager.persist(bbc); + entityManager.persist(eurosport); + entityManager.persist(hbo); + + User user1 = new User(); + user1.setEmail("user1@gmail.com"); + user1.setSubscriptionId(single.getId()); + + entityManager.persist(user1); + + entityManager.getTransaction().commit(); + } +}