blob: d0877f041a23294d8d355ff4a37f664115284669 [file] [log] [blame]
/*
* Copyright (c) 2005, 2021 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 (Employee emp : result) {
Employee emp1 = 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);
}
}
}