Search in sources :

Example 6 with IdentityHashSet

use of org.eclipse.persistence.internal.helper.IdentityHashSet in project eclipselink by eclipse-ee4j.

the class NestedFetchGroupTests method internalDynamicHierarchicalFetchGroup_JOIN_FETCH.

void internalDynamicHierarchicalFetchGroup_JOIN_FETCH(boolean useCopy) throws Exception {
    EntityManager em = createEntityManager("fieldaccess");
    try {
        beginTransaction(em);
        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName");
        query.setParameter("LNAME", "%");
        // Define the fields to be fetched on Employee
        FetchGroup fg = new FetchGroup();
        fg.addAttribute("firstName");
        fg.addAttribute("lastName");
        fg.addAttribute("manager.firstName");
        fg.addAttribute("manager.salary");
        fg.addAttribute("manager.manager");
        query.setHint(QueryHints.FETCH_GROUP, fg);
        // applied to the selected Employee who is not a manager of some other selected Employee
        FetchGroup employeeFG = new EntityFetchGroup(new String[] { "id", "version", "firstName", "lastName", "manager" });
        // applied to the manager of a selected Employee who is not selected as an Employee
        FetchGroup managerFG = new EntityFetchGroup(new String[] { "id", "version", "firstName", "salary", "manager" });
        // applied to the object which is both selected as an Employee and the manager of another selected Employee
        FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG, false);
        // used in useCopy case only
        FetchGroup employeeManagerManagerFG = null;
        if (useCopy) {
            employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup(), false);
        }
        /*
             * These are the first names of Employees involved; --> means "managed by".
             * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager).
             *
             * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null
             * Charles -----^   Marius ----^
             *
             * Nancy ------> Sarah-loo ---> null
             *
             * Sarah, Charles, Nancy should have employeeFG;
             * Sarah-loo - managerFG;
             * Bob, Marius - employeeManagerFG;
             * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager}
             * Jill should have a union of two groups:  {firstName,salary,manager}, {manager}
             * The result for all three of them is the same:
             *   in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null;
             *   in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup).
             * That's how leaf reference attribute is treated:
             *   default fetch group for read;
             *   NonReferenceEntityFetchGroup (see FetchGroupManager) for copy.
             * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager},
             *   in useCopy == true case additional manager comes from another fetch group (they all contain manager).
             */
        List<Employee> emps = query.getResultList();
        if (useCopy) {
            /*for(Employee emp : emps) {
                    int idHashCode =  System.identityHashCode(emp);
                    System.out.println(emp.getFirstName() + '\t' + idHashCode);
                }*/
            emps = (List) JpaHelper.getEntityManager(em).copy(emps, fg);
        }
        // Sets of managed Employees keyed by their manager
        Map<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap();
        for (Employee emp : emps) {
            Employee manager = emp.getManager();
            Set<Employee> managedEmployees = managedEmployeesByManager.get(manager);
            if (managedEmployees == null) {
                managedEmployees = new IdentityHashSet();
                managedEmployeesByManager.put(manager, managedEmployees);
            }
            managedEmployees.add(emp);
        }
        for (Employee emp : emps) {
            Set<Employee> managedEmployees = managedEmployeesByManager.get(emp);
            Employee manager = emp.getManager();
            if (managedEmployees == null) {
                // employee is NOT a manager of any of the selected employees:
                assertFetched(emp, employeeFG);
                Set<Employee> managedByManagerEmployees = managedEmployeesByManager.get(manager);
                // indicates whether one of manager's managed employees is a manager itself
                boolean isManagersManager = false;
                for (Employee managedEmp : managedByManagerEmployees) {
                    if (managedEmployeesByManager.containsKey(managedEmp)) {
                        isManagersManager = true;
                        break;
                    }
                }
                if (isManagersManager) {
                    if (useCopy) {
                        // for at least one of the selected employees manager is manager's manager:
                        // someSelectedEmp.getManager().getManager() == manager
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
                        // for another employee it's just a manager - which means it should include "manager":
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
                        assertFetched(manager, employeeManagerManagerFG);
                    } else {
                        // for at least one of the selected employees manager is manager's manager:
                        // someSelectedEmp.getManager().getManager() == manager
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                        // which means no fetch group should be used.
                        assertNoFetchGroup(manager);
                    }
                } else {
                    // it's not manager's manager
                    if (emps.contains(manager)) {
                        // it's a manager of one of the selected Employees, and selected itself.
                        assertFetched(manager, employeeManagerFG);
                    } else {
                        // it's a manager of one of the selected Employees, but not selected itself.
                        assertFetched(manager, managerFG);
                    }
                }
            } else {
                // employee is a manager of at least one of the selected employees
                // indicates whether one of emp's managed employees is a manager itself
                boolean isManagersManager = false;
                for (Employee managedEmp : managedEmployees) {
                    if (managedEmployeesByManager.containsKey(managedEmp)) {
                        isManagersManager = true;
                        break;
                    }
                }
                if (isManagersManager) {
                    if (useCopy) {
                        // for at least one of the selected employees manager is manager's manager:
                        // someSelectedEmp.getManager().getManager() == manager
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
                        // for another employee it's just a manager - which means it should include "manager":
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
                        assertFetched(emp, employeeManagerManagerFG);
                    } else {
                        // for at least one of the selected employees emp is manager's manager:
                        // someSelectedEmp.getManager().getManager() == emp
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                        // which means no fetch group should be used.
                        assertNoFetchGroup(emp);
                    }
                } else {
                    // it's selected employee, manager of some selected employee, but not manager's manager
                    assertFetched(emp, employeeManagerFG);
                }
                if (useCopy) {
                    // for at least one of the selected employees manager is manager's manager:
                    // someSelectedEmp.getManager().getManager() == manager
                    // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                    // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
                    // for another employee it's just a manager - which means it should include "manager":
                    // employeeManagerManagerFG is the union of these two EntityFetchGroups.
                    assertFetched(manager, employeeManagerManagerFG);
                } else {
                    // for at least one of the selected employees manager is manager's manager:
                    // someSelectedEmp.getManager().getManager() == manager
                    // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item,
                    // which means no fetch group should be used.
                    assertNoFetchGroup(manager);
                }
            }
        }
    } finally {
        if (isTransactionActive(em)) {
            rollbackTransaction(em);
        }
        closeEntityManager(em);
    }
}
Also used : EntityFetchGroup(org.eclipse.persistence.internal.queries.EntityFetchGroup) IdentityHashSet(org.eclipse.persistence.internal.helper.IdentityHashSet) EntityManager(jakarta.persistence.EntityManager) Employee(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Employee) IdentityHashSet(org.eclipse.persistence.internal.helper.IdentityHashSet) Set(java.util.Set) Query(jakarta.persistence.Query) IdentityHashMap(java.util.IdentityHashMap) FetchGroup(org.eclipse.persistence.queries.FetchGroup) EntityFetchGroup(org.eclipse.persistence.internal.queries.EntityFetchGroup)

Example 7 with IdentityHashSet

use of org.eclipse.persistence.internal.helper.IdentityHashSet in project eclipselink by eclipse-ee4j.

the class NestedFetchGroupTests method internalDynamicHierarchicalFetchGroup_JOIN_FETCH.

void internalDynamicHierarchicalFetchGroup_JOIN_FETCH(boolean useCopy) throws Exception {
    EntityManager em = createEntityManager();
    try {
        beginTransaction(em);
        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.manager WHERE e.lastName LIKE :LNAME AND e.manager.lastName <> e.lastName");
        query.setParameter("LNAME", "%");
        // Define the fields to be fetched on Employee
        FetchGroup fg = new FetchGroup();
        fg.addAttribute("firstName");
        fg.addAttribute("lastName");
        fg.addAttribute("manager.firstName");
        fg.addAttribute("manager.salary");
        fg.addAttribute("manager.manager");
        query.setHint(QueryHints.FETCH_GROUP, fg);
        // applied to the selected Employee who is not a manager of some other selected Employee
        FetchGroup employeeFG = new EntityFetchGroup(new String[] { "id", "version", "firstName", "lastName", "manager" });
        // applied to the manager of a selected Employee who is not selected as an Employee
        FetchGroup managerFG = new EntityFetchGroup(new String[] { "id", "version", "firstName", "salary", "manager" });
        // applied to the object which is both selected as an Employee and the manager of another selected Employee
        FetchGroup employeeManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(employeeFG, managerFG, false);
        // used in useCopy case only
        FetchGroup employeeManagerManagerFG = null;
        if (useCopy) {
            employeeManagerManagerFG = employeeDescriptor.getFetchGroupManager().flatUnionFetchGroups(new EntityFetchGroup("manager"), employeeDescriptor.getFetchGroupManager().getNonReferenceEntityFetchGroup(), false);
        }
        /*
             * These are the first names of Employees involved; --> means "managed by".
             * All the employees here are returned by the query except Jill and Sarah-loo (they got no manager).
             *
             * Sarah ------>Bob -------> John ----> Jim-bob ---> Jill ---> null
             * Charles -----^   Marius ----^
             *
             * Nancy ------> Sarah-loo ---> null
             *
             * Sarah, Charles, Nancy should have employeeFG;
             * Sarah-loo - managerFG;
             * Bob, Marius - employeeManagerFG;
             * John, Jim-bob should have a union of three fetch groups: {firstName,lastName,manager}, {firstName,salary,manager}, {manager}
             * Jill should have a union of two groups:  {firstName,salary,manager}, {manager}
             * The result for all three of them is the same:
             *   in read case (useCopy == false) it should be null (no fetch group), because defaultFetchGroup is null;
             *   in copy case (useCopy == true) it should be a union of "manager" and all non relational attributes (NonReferenceEntityFetchGroup).
             * That's how leaf reference attribute is treated:
             *   default fetch group for read;
             *   NonReferenceEntityFetchGroup (see FetchGroupManager) for copy.
             * In this test defaultFetchGroup (null) / NonReferenceEntityFetchGroup comes from {manager},
             *   in useCopy == true case additional manager comes from another fetch group (they all contain manager).
             */
        List<Employee> emps = query.getResultList();
        if (useCopy) {
            /*for(Employee emp : emps) {
                    int idHashCode =  System.identityHashCode(emp);
                    System.out.println(emp.getFirstName() + '\t' + idHashCode);
                }*/
            emps = (List) JpaHelper.getEntityManager(em).copy(emps, fg);
        }
        // Sets of managed Employees keyed by their manager
        Map<Employee, Set<Employee>> managedEmployeesByManager = new IdentityHashMap();
        for (Employee emp : emps) {
            Employee manager = emp.getManager();
            Set<Employee> managedEmployees = managedEmployeesByManager.get(manager);
            if (managedEmployees == null) {
                managedEmployees = new IdentityHashSet();
                managedEmployeesByManager.put(manager, managedEmployees);
            }
            managedEmployees.add(emp);
        }
        for (Employee emp : emps) {
            Set<Employee> managedEmployees = managedEmployeesByManager.get(emp);
            Employee manager = emp.getManager();
            if (managedEmployees == null) {
                // employee is NOT a manager of any of the selected employees:
                assertFetched(emp, employeeFG);
                Set<Employee> managedByManagerEmployees = managedEmployeesByManager.get(manager);
                // indicates whether one of manager's managed employees is a manager itself
                boolean isManagersManager = false;
                for (Employee managedEmp : managedByManagerEmployees) {
                    if (managedEmployeesByManager.containsKey(managedEmp)) {
                        isManagersManager = true;
                        break;
                    }
                }
                if (isManagersManager) {
                    if (useCopy) {
                        // for at least one of the selected employees manager is manager's manager:
                        // someSelectedEmp.getManager().getManager() == manager
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
                        // for another employee it's just a manager - which means it should include "manager":
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
                        assertFetched(manager, employeeManagerManagerFG);
                    } else {
                        // for at least one of the selected employees manager is manager's manager:
                        // someSelectedEmp.getManager().getManager() == manager
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                        // which means no fetch group should be used.
                        assertNoFetchGroup(manager);
                    }
                } else {
                    // it's not manager's manager
                    if (emps.contains(manager)) {
                        // it's a manager of one of the selected Employees, and selected itself.
                        assertFetched(manager, employeeManagerFG);
                    } else {
                        // it's a manager of one of the selected Employees, but not selected itself.
                        assertFetched(manager, managerFG);
                    }
                }
            } else {
                // employee is a manager of at least one of the selected employees
                // indicates whether one of emp's managed employees is a manager itself
                boolean isManagersManager = false;
                for (Employee managedEmp : managedEmployees) {
                    if (managedEmployeesByManager.containsKey(managedEmp)) {
                        isManagersManager = true;
                        break;
                    }
                }
                if (isManagersManager) {
                    if (useCopy) {
                        // for at least one of the selected employees manager is manager's manager:
                        // someSelectedEmp.getManager().getManager() == manager
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                        // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
                        // for another employee it's just a manager - which means it should include "manager":
                        // employeeManagerManagerFG is the union of these two EntityFetchGroups.
                        assertFetched(emp, employeeManagerManagerFG);
                    } else {
                        // for at least one of the selected employees emp is manager's manager:
                        // someSelectedEmp.getManager().getManager() == emp
                        // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                        // which means no fetch group should be used.
                        assertNoFetchGroup(emp);
                    }
                } else {
                    // it's selected employee, manager of some selected employee, but not manager's manager
                    assertFetched(emp, employeeManagerFG);
                }
                if (useCopy) {
                    // for at least one of the selected employees manager is manager's manager:
                    // someSelectedEmp.getManager().getManager() == manager
                    // That means for someSelectedEmp emp is defined by {manager.manager} FetchGroup's item,
                    // which means NonReferenceEntityFetchGroup (only non-reference attributes + pk)
                    // for another employee it's just a manager - which means it should include "manager":
                    // employeeManagerManagerFG is the union of these two EntityFetchGroups.
                    assertFetched(manager, employeeManagerManagerFG);
                } else {
                    // for at least one of the selected employees manager is manager's manager:
                    // someSelectedEmp.getManager().getManager() == manager
                    // That means for someSelectedEmp emp.getManager() is defined by {manager.manager} FetchGroup's item,
                    // which means no fetch group should be used.
                    assertNoFetchGroup(manager);
                }
            }
        }
    } finally {
        if (isTransactionActive(em)) {
            rollbackTransaction(em);
        }
        closeEntityManager(em);
    }
}
Also used : EntityFetchGroup(org.eclipse.persistence.internal.queries.EntityFetchGroup) IdentityHashSet(org.eclipse.persistence.internal.helper.IdentityHashSet) EntityManager(jakarta.persistence.EntityManager) Employee(org.eclipse.persistence.testing.models.jpa.advanced.Employee) IdentityHashSet(org.eclipse.persistence.internal.helper.IdentityHashSet) Set(java.util.Set) Query(jakarta.persistence.Query) IdentityHashMap(java.util.IdentityHashMap) FetchGroup(org.eclipse.persistence.queries.FetchGroup) EntityFetchGroup(org.eclipse.persistence.internal.queries.EntityFetchGroup)

Aggregations

IdentityHashSet (org.eclipse.persistence.internal.helper.IdentityHashSet)7 EntityManager (jakarta.persistence.EntityManager)4 Query (jakarta.persistence.Query)4 Set (java.util.Set)3 TypedQuery (jakarta.persistence.TypedQuery)2 ArrayList (java.util.ArrayList)2 IdentityHashMap (java.util.IdentityHashMap)2 EntityFetchGroup (org.eclipse.persistence.internal.queries.EntityFetchGroup)2 JpaEntityManager (org.eclipse.persistence.jpa.JpaEntityManager)2 FetchGroup (org.eclipse.persistence.queries.FetchGroup)2 CopyGroup (org.eclipse.persistence.sessions.CopyGroup)2 Employee (org.eclipse.persistence.testing.models.jpa.advanced.Employee)2 Employee (org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Employee)2 HashSet (java.util.HashSet)1 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)1 PhoneNumber (org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber)1 Project (org.eclipse.persistence.testing.models.jpa.advanced.Project)1 PhoneNumber (org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.PhoneNumber)1 Project (org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Project)1