| /* |
| * Copyright (c) 2005, 2020 Oracle and/or its affiliates. All rights reserved. |
| * Copyright (c) 2005, 2015 SAP. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // SAP - initial API and implementation |
| |
| package org.eclipse.persistence.testing.tests.wdf.jpa1.query; |
| |
| import java.sql.SQLException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import jakarta.persistence.EntityManager; |
| import jakarta.persistence.Query; |
| |
| import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment; |
| import org.eclipse.persistence.testing.framework.wdf.ToBeInvestigated; |
| import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Department; |
| import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Employee; |
| import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Hobby; |
| import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Project; |
| import org.eclipse.persistence.testing.models.wdf.jpa1.node.Node; |
| import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base; |
| import org.junit.Test; |
| |
| public class TestJoinFetch extends JPA1Base { |
| |
| // private final DatabaseStatisticsRequestManager databaseStatistics = |
| // OpenSQLServices.getDatabaseStatisticsRequestManager(); |
| |
| private final static String description = "description_"; |
| |
| private static final Map<Integer, Employee> employeeStore = new HashMap<Integer, Employee>(); |
| |
| private void init() throws SQLException { |
| clearAllTables(); |
| employeeStore.clear(); |
| JPAEnvironment env = getEnvironment(); |
| EntityManager em = env.getEntityManager(); |
| try { |
| env.beginTransaction(em); |
| for (int depNo = 1; depNo <= 3; depNo++) { |
| Department department = new Department(depNo, "dep_" + depNo); |
| em.persist(department); |
| |
| for (int empNo = 1; empNo <= depNo + 2; empNo++) { |
| int id = 10 * depNo + empNo; |
| Employee employee = new Employee(id, "first_" + id, "last_" + id, department); |
| List<Hobby> hobbies = new ArrayList<Hobby>(); |
| Set<Project> projects = new HashSet<Project>(); |
| for (int hobbyCount = 0; hobbyCount < empNo; hobbyCount++) { |
| Project project = new Project(); |
| project.setName(description + hobbyCount); |
| Set<Employee> employees = new HashSet<Employee>(1); |
| employees.add(employee); |
| |
| project.setEmployees(employees); |
| projects.add(project); |
| Hobby hobby = new Hobby(); |
| em.persist(hobby); |
| |
| hobby.setDescription(description + hobby.getId()); |
| hobbies.add(hobby); |
| } |
| em.persist(employee); |
| for (Project proj : projects) { |
| em.persist(proj); |
| } |
| employee.setProjects(projects); |
| employee.setHobbies(hobbies); |
| em.merge(employee); |
| for (Project proj : projects) { |
| em.merge(proj); |
| } |
| employeeStore.put(employee.getId(), employee); |
| |
| } |
| } |
| |
| Node parent = new Node(1, null); |
| Node child1 = new Node(2, parent); |
| Node child2 = new Node(3, parent); |
| em.persist(parent); |
| em.persist(child1); |
| em.persist(child2); |
| |
| env.commitTransactionAndClear(em); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| @Test |
| public void testJoinFetchDepartment() throws SQLException { |
| init(); |
| EntityManager em = getEnvironment().getEntityManager(); |
| try { |
| Query query = em.createQuery("select e from Employee e join fetch e.department"); |
| List<?> result = query.getResultList(); |
| |
| verify(result.size() == 12, "wrong size"); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Test |
| public void testJoinFetchProjects() throws SQLException { |
| init(); |
| EntityManager em = getEnvironment().getEntityManager(); |
| try { |
| Query q = em.createQuery("SELECT DISTINCT e FROM Employee e JOIN FETCH e.projects"); |
| List<Employee> result = q.getResultList(); |
| verify(result.size() == 12, "wrong size of result list. expected 12, got " + result.size()); |
| |
| for (Employee emp : result) { |
| verify(emp.getProjects() != null, "the field projects in employee " + emp.getId() |
| + " is null. It shold at least be populated with an empty list."); |
| // the project should at least have a back reference to emp |
| |
| for (Project proj : emp.getProjects()) { |
| boolean found = false; |
| for (Object backEmp : proj.getEmployees()) { |
| if (((Employee) backEmp).getId() == emp.getId()) { |
| found = true; |
| } |
| } |
| verify(found, "could not find back reference from project " + proj.getId() + " to employee + " |
| + emp.getId()); |
| } |
| } |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| private void countStatements(String jpql, int rows, int statements) throws SQLException { |
| init(); |
| EntityManager em = getEnvironment().getEntityManager(); |
| try { |
| // final DatabaseStatisticsRecord record = databaseStatistics.start("testCountStatements"); |
| Query query = em.createQuery(jpql); |
| @SuppressWarnings("unused") |
| List<?> result = query.getResultList(); |
| // databaseStatistics.stop(record); |
| // if(record != null && record.getExecuteQueryCount() > 0) { |
| // assertTrue("The number of monitored SQL statements ("+ record.getExecuteQueryCount() +")" + |
| // " does not match the number of expected statemetns ("+ statements +").", |
| // record.getExecuteQueryCount() == statements); |
| // } |
| // |
| // verify(result.size() == rows, "wrong size; expected " + rows + " - got " + result.size()); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| @Test |
| public void testOneNode() throws SQLException { |
| countStatements("select n from Node n join fetch n.parent where n.id = 2", 1, 1); |
| } |
| |
| @Test |
| public void testTwoNodes() throws SQLException { |
| countStatements("select n from Node n join fetch n.parent where n.id <> 1", 2, 1); |
| } |
| |
| @Test |
| public void testJoinFetchHobbies() throws SQLException { |
| init(); |
| EntityManager em = getEnvironment().getEntityManager(); |
| try { |
| Query query = em.createQuery("select e from Employee e join fetch e.hobbies"); |
| List<?> result = query.getResultList(); |
| |
| verify(result.size() == 31, "wrong size; expected 31 - got " + result.size()); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Test |
| // @TestProperties(unsupportedEnvironments={JTAEnvironment.class}) |
| @ToBeInvestigated |
| public void testDistinctJoinFetchHobbies() throws SQLException { |
| init(); |
| EntityManager em = getEnvironment().getEntityManager(); |
| |
| try { |
| getEnvironment().beginTransaction(em); |
| Query query = em.createQuery("select distinct e from Employee e join fetch e.hobbies ORDER BY e.id"); |
| List<Employee> result = query.getResultList(); |
| getEnvironment().commitTransactionAndClear(em); |
| |
| verify(result.size() == 12, "wrong size; expected 12 - got " + result.size()); |
| // check for fetch-joined hobbies in query-result employees |
| for (Employee emp : result) { |
| verify(emp.getHobbies().size() > 0, |
| "fetch-joined hobbies were not attached to the entity after query execution."); |
| } |
| |
| for (Object emp : result) { |
| Employee emp1 = (Employee) emp; |
| Employee compareEmp = employeeStore.get(emp1.getId()); |
| |
| Comparator<Hobby> comp = new Comparator<Hobby>() { |
| @Override |
| public int compare(Hobby o1, Hobby o2) { |
| return String.CASE_INSENSITIVE_ORDER.compare(o1.getDescription(), o2.getDescription()); |
| } |
| }; |
| |
| Collections.sort(compareEmp.getHobbies(), comp); |
| Collections.reverse(compareEmp.getHobbies()); |
| |
| for (int i = 0; i < emp1.getHobbies().size(); i++) { |
| if (!compareEmp.getHobbies().get(i).getId().equals(emp1.getHobbies().get(i).getId())) { |
| verify(false, "did not find expected hobby " + emp1.getHobbies().get(i).getId() |
| + " attached to returned entity employee with ID " + emp1.getId() + " instead employee " |
| + compareEmp.getId() + " with hobby " + compareEmp.getHobbies().get(i).getId() + " was found."); |
| |
| } |
| } |
| } |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| @Test |
| public void testDistinctJoinFetchHobbiesWithMultipleSelectItems() throws SQLException { |
| init(); |
| EntityManager em = getEnvironment().getEntityManager(); |
| try { |
| Query query = em.createQuery("select distinct e, e from Employee e join fetch e.hobbies"); |
| List<?> result = query.getResultList(); |
| verify(result.size() == 12, "wrong size; expected 12 - got " + result.size()); |
| } finally { |
| closeEntityManager(em); |
| } |
| } |
| |
| } |