Search in sources :

Example 1 with IndirectCollection

use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.

the class NestedDefaultFetchGroupTests method internalFindMinEmployee.

void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) {
    EntityManager em = createEntityManager("fieldaccess");
    beginTransaction(em);
    int minId = minEmployeeIdWithAddressAndPhones(em);
    assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
    boolean load = false;
    boolean originalLoad = false;
    if (!useLoadGroup) {
        assertTrue(loadAddress == loadPhones);
        load = loadAddress;
        originalLoad = defaultEmployeeFG.shouldLoad();
        if (load != originalLoad) {
            defaultEmployeeFG.setShouldLoad(load);
        }
    }
    try {
        Employee emp;
        if (useLoadGroup) {
            LoadGroup lg = defaultEmployeeFG.toLoadGroup();
            if (!loadAddress) {
                lg.removeAttribute("address");
            }
            if (!loadPhones) {
                lg.removeAttribute("phoneNumbers");
            }
            HashMap<String, Object> hints = new HashMap(1);
            hints.put(QueryHints.LOAD_GROUP, lg);
            emp = em.find(Employee.class, minId, hints);
        } else {
            emp = em.find(Employee.class, minId);
        }
        assertNotNull(emp);
        int nExpected = 2;
        if (loadAddress) {
            nExpected++;
        }
        if (loadPhones) {
            nExpected++;
        }
        assertEquals(nExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        boolean addressInstantiated = ((ValueHolderInterface) employeeDescriptor.getMappingForAttributeName("address").getAttributeValueFromObject(emp)).isInstantiated();
        assertTrue(loadAddress == addressInstantiated);
        boolean phonesInstantiated = ((IndirectCollection) employeeDescriptor.getMappingForAttributeName("phoneNumbers").getAttributeValueFromObject(emp)).isInstantiated();
        assertTrue(loadPhones == phonesInstantiated);
        emp.getAddress();
        emp.getPhoneNumbers().size();
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        assertFetched(emp, defaultEmployeeFG);
        assertFetchedAttribute(emp, "address");
        assertFetchedAttribute(emp, "phoneNumbers");
        // Check Address
        FetchGroup fgAddress = defaultEmployeeFG.getGroup("address");
        assertFetched(emp.getAddress(), fgAddress);
        // Check phones
        FetchGroup fgPhones = defaultEmployeeFG.getGroup("phoneNumbers");
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
            assertFetched(phone, fgPhones);
        }
    } finally {
        if (!useLoadGroup) {
            if (load != originalLoad) {
                defaultEmployeeFG.setShouldLoad(originalLoad);
            }
        }
        if (isTransactionActive(em)) {
            rollbackTransaction(em);
        }
        closeEntityManager(em);
    }
}
Also used : HashMap(java.util.HashMap) LoadGroup(org.eclipse.persistence.queries.LoadGroup) IndirectCollection(org.eclipse.persistence.indirection.IndirectCollection) EntityManager(jakarta.persistence.EntityManager) Employee(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Employee) ValueHolderInterface(org.eclipse.persistence.indirection.ValueHolderInterface) FetchGroup(org.eclipse.persistence.queries.FetchGroup) PhoneNumber(org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.PhoneNumber)

Example 2 with IndirectCollection

use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.

the class NestedDefaultFetchGroupTests method internalFindMinEmployee.

void internalFindMinEmployee(boolean loadAddress, boolean loadPhones, boolean useLoadGroup) {
    EntityManager em = createEntityManager();
    beginTransaction(em);
    int minId = minEmployeeIdWithAddressAndPhones(em);
    assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
    boolean load = false;
    boolean originalLoad = false;
    if (!useLoadGroup) {
        assertTrue(loadAddress == loadPhones);
        load = loadAddress;
        originalLoad = defaultEmployeeFG.shouldLoad();
        if (load != originalLoad) {
            defaultEmployeeFG.setShouldLoad(load);
        }
    }
    try {
        Employee emp;
        if (useLoadGroup) {
            LoadGroup lg = defaultEmployeeFG.toLoadGroup();
            if (!loadAddress) {
                lg.removeAttribute("address");
            }
            if (!loadPhones) {
                lg.removeAttribute("phoneNumbers");
            }
            HashMap<String, Object> hints = new HashMap(1);
            hints.put(QueryHints.LOAD_GROUP, lg);
            emp = em.find(Employee.class, minId, hints);
        } else {
            emp = em.find(Employee.class, minId);
        }
        assertNotNull(emp);
        int nExpected = 2;
        if (loadAddress) {
            nExpected++;
        }
        if (loadPhones) {
            nExpected++;
        }
        assertEquals(nExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        boolean addressInstantiated = ((ValueHolderInterface) employeeDescriptor.getMappingForAttributeName("address").getAttributeValueFromObject(emp)).isInstantiated();
        assertTrue(loadAddress == addressInstantiated);
        boolean phonesInstantiated = ((IndirectCollection) employeeDescriptor.getMappingForAttributeName("phoneNumbers").getAttributeValueFromObject(emp)).isInstantiated();
        assertTrue(loadPhones == phonesInstantiated);
        emp.getAddress();
        emp.getPhoneNumbers().size();
        assertEquals(4, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        assertFetched(emp, defaultEmployeeFG);
        assertFetchedAttribute(emp, "address");
        assertFetchedAttribute(emp, "phoneNumbers");
        // Check Address
        FetchGroup fgAddress = defaultEmployeeFG.getGroup("address");
        assertFetched(emp.getAddress(), fgAddress);
        // Check phones
        FetchGroup fgPhones = defaultEmployeeFG.getGroup("phoneNumbers");
        for (PhoneNumber phone : emp.getPhoneNumbers()) {
            assertFetched(phone, fgPhones);
        }
    } finally {
        if (!useLoadGroup) {
            if (load != originalLoad) {
                defaultEmployeeFG.setShouldLoad(originalLoad);
            }
        }
        if (isTransactionActive(em)) {
            rollbackTransaction(em);
        }
        closeEntityManager(em);
    }
}
Also used : HashMap(java.util.HashMap) LoadGroup(org.eclipse.persistence.queries.LoadGroup) IndirectCollection(org.eclipse.persistence.indirection.IndirectCollection) EntityManager(jakarta.persistence.EntityManager) Employee(org.eclipse.persistence.testing.models.jpa.advanced.Employee) ValueHolderInterface(org.eclipse.persistence.indirection.ValueHolderInterface) FetchGroup(org.eclipse.persistence.queries.FetchGroup) PhoneNumber(org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber)

Example 3 with IndirectCollection

use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.

the class JUnitJPQLComplexTestSuite method testJoinFetchWithJoin.

// Bug 303767 - fixed with Hermes.
// Test that the same attribute can be joined and join fetched.
public void testJoinFetchWithJoin() {
    if (!isHermesParser()) {
        warning("testJoinFetchWithJoin only works with Hermes");
        return;
    }
    clearCache();
    EntityManager em = createEntityManager();
    Query query = em.createQuery("Select e from Employee e join fetch e.phoneNumbers join e.phoneNumbers p where p.areaCode <> '613'");
    Employee employee = (Employee) query.getResultList().get(0);
    if (isWeavingEnabled()) {
        if ((employee.getPhoneNumbers() instanceof IndirectCollection) && !((IndirectCollection) employee.getPhoneNumbers()).isInstantiated()) {
            fail("Join fetch did not occur.");
        }
    }
    clearCache();
    em.clear();
    query = em.createQuery("Select e from Employee e join e.phoneNumbers p join fetch e.phoneNumbers where p.areaCode <> '613'");
    employee = (Employee) query.getResultList().get(0);
    if (isWeavingEnabled()) {
        if ((employee.getPhoneNumbers() instanceof IndirectCollection) && !((IndirectCollection) employee.getPhoneNumbers()).isInstantiated()) {
            fail("Join fetch did not occur.");
        }
    }
    closeEntityManager(em);
}
Also used : EntityManager(jakarta.persistence.EntityManager) JpaEntityManager(org.eclipse.persistence.jpa.JpaEntityManager) Employee(org.eclipse.persistence.testing.models.jpa.advanced.Employee) Query(jakarta.persistence.Query) ReadObjectQuery(org.eclipse.persistence.queries.ReadObjectQuery) ReportQuery(org.eclipse.persistence.queries.ReportQuery) DatabaseQuery(org.eclipse.persistence.queries.DatabaseQuery) ReadAllQuery(org.eclipse.persistence.queries.ReadAllQuery) IndirectCollection(org.eclipse.persistence.indirection.IndirectCollection)

Example 4 with IndirectCollection

use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.

the class DirectCollectionMapping method mergeChangesIntoObject.

/**
 * INTERNAL:
 * Merge changes from the source to the target object.
 * Because this is a collection mapping, values are added to or removed from the
 * collection based on the changeset
 */
@Override
public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
    if (this.descriptor.getCachePolicy().isProtectedIsolation() && !this.isCacheable && !targetSession.isProtectedSession()) {
        setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null)));
        return;
    }
    ContainerPolicy containerPolicy = getContainerPolicy();
    Object valueOfTarget = null;
    AbstractSession session = mergeManager.getSession();
    DirectCollectionChangeRecord directCollectionChangeRecord = (DirectCollectionChangeRecord) changeRecord;
    // Check to see if the target has an instantiated collection
    if ((isAttributeValueInstantiated(target)) && (!changeRecord.getOwner().isNew())) {
        if (isSynchronizeOnMerge) {
            valueOfTarget = getRealCollectionAttributeValueFromObject(target, session);
        } else {
            valueOfTarget = containerPolicy.cloneFor(getRealCollectionAttributeValueFromObject(target, session));
        }
    } else {
        // if not create an instance of the collection
        valueOfTarget = containerPolicy.containerInstance(directCollectionChangeRecord.getAddObjectMap().size());
    }
    if (!isAttributeValueInstantiated(target)) {
        if (mergeManager.shouldMergeChangesIntoDistributedCache()) {
            return;
        }
        for (Object iterator = containerPolicy.iteratorFor(getRealCollectionAttributeValueFromObject(source, session)); containerPolicy.hasNext(iterator); ) {
            containerPolicy.addInto(containerPolicy.next(iterator, session), valueOfTarget, session);
        }
    } else {
        Object synchronizationTarget = valueOfTarget;
        // not the wrapper as the clone synchs on the delegate, see bug#5685287.
        if (valueOfTarget instanceof IndirectCollection) {
            synchronizationTarget = ((IndirectCollection) valueOfTarget).getDelegateObject();
            if (((DirectCollectionChangeRecord) changeRecord).orderHasBeenRepaired() && (valueOfTarget instanceof IndirectList)) {
                ((IndirectList) valueOfTarget).setIsListOrderBrokenInDb(false);
            }
        }
        if (isSynchronizeOnMerge) {
            synchronized (synchronizationTarget) {
                mergeAddRemoveChanges(valueOfTarget, synchronizationTarget, directCollectionChangeRecord, mergeManager, session);
            }
        } else {
            mergeAddRemoveChanges(valueOfTarget, synchronizationTarget, directCollectionChangeRecord, mergeManager, session);
        }
    }
    setRealAttributeValueInObject(target, valueOfTarget);
}
Also used : OrderedListContainerPolicy(org.eclipse.persistence.internal.queries.OrderedListContainerPolicy) ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) DirectCollectionChangeRecord(org.eclipse.persistence.internal.sessions.DirectCollectionChangeRecord) ValueHolder(org.eclipse.persistence.indirection.ValueHolder) IndirectCollection(org.eclipse.persistence.indirection.IndirectCollection) IndirectList(org.eclipse.persistence.indirection.IndirectList) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 5 with IndirectCollection

use of org.eclipse.persistence.indirection.IndirectCollection in project eclipselink by eclipse-ee4j.

the class DirectMapMapping method mergeChangesIntoObject.

/**
 * INTERNAL:
 * Merge changes from the source to the target object.
 * Because this is a collection mapping, values are added to or removed from the
 * collection based on the changeset.
 */
@Override
public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
    if (this.descriptor.getCachePolicy().isProtectedIsolation() && !this.isCacheable && !targetSession.isProtectedSession()) {
        setAttributeValueInObject(target, this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null)));
        return;
    }
    Map valueOfTarget = null;
    AbstractSession session = mergeManager.getSession();
    // collect the changes into a vector
    HashMap addObjects = ((DirectMapChangeRecord) changeRecord).getAddObjects();
    HashMap removeObjects = ((DirectMapChangeRecord) changeRecord).getRemoveObjects();
    // Check to see if the target has an instantiated collection
    if ((isAttributeValueInstantiated(target)) && (!changeRecord.getOwner().isNew())) {
        valueOfTarget = (Map) getRealCollectionAttributeValueFromObject(target, session);
    } else {
        // if not create an instance of the map
        valueOfTarget = (Map) containerPolicy.containerInstance(addObjects.size());
    }
    if (!isAttributeValueInstantiated(target)) {
        if (mergeManager.shouldMergeChangesIntoDistributedCache()) {
            return;
        }
        Object valueOfSource = getRealCollectionAttributeValueFromObject(source, session);
        for (Object iterator = containerPolicy.iteratorFor(valueOfSource); containerPolicy.hasNext(iterator); ) {
            Map.Entry entry = (Map.Entry) containerPolicy.nextEntry(iterator, session);
            containerPolicy.addInto(entry.getKey(), entry.getValue(), valueOfTarget, session);
        }
    } else {
        Object synchronizationTarget = valueOfTarget;
        // not the wrapper as the clone synchs on the delegate, see bug#5685287.
        if (valueOfTarget instanceof IndirectCollection) {
            synchronizationTarget = ((IndirectCollection) valueOfTarget).getDelegateObject();
        }
        synchronized (synchronizationTarget) {
            // Next iterate over the changes and add them to the container
            for (Iterator i = removeObjects.keySet().iterator(); i.hasNext(); ) {
                Object keyToRemove = i.next();
                containerPolicy.removeFrom(keyToRemove, null, valueOfTarget, session);
            }
            for (Iterator i = addObjects.keySet().iterator(); i.hasNext(); ) {
                Object keyToAdd = i.next();
                Object nextItem = addObjects.get(keyToAdd);
                if (mergeManager.shouldMergeChangesIntoDistributedCache()) {
                    // bug#4458089 and 4454532- check if collection contains new item before adding during merge into distributed cache
                    if (!containerPolicy.contains(nextItem, valueOfTarget, session)) {
                        containerPolicy.addInto(keyToAdd, nextItem, valueOfTarget, session);
                    }
                } else {
                    containerPolicy.addInto(keyToAdd, nextItem, valueOfTarget, session);
                }
            }
        }
    }
    setRealAttributeValueInObject(target, valueOfTarget);
}
Also used : DirectMapChangeRecord(org.eclipse.persistence.internal.sessions.DirectMapChangeRecord) HashMap(java.util.HashMap) Iterator(java.util.Iterator) DescriptorIterator(org.eclipse.persistence.internal.descriptors.DescriptorIterator) ValueHolder(org.eclipse.persistence.indirection.ValueHolder) IndirectCollection(org.eclipse.persistence.indirection.IndirectCollection) Map(java.util.Map) HashMap(java.util.HashMap) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Aggregations

IndirectCollection (org.eclipse.persistence.indirection.IndirectCollection)6 EntityManager (jakarta.persistence.EntityManager)4 HashMap (java.util.HashMap)3 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)3 Employee (org.eclipse.persistence.testing.models.jpa.advanced.Employee)3 Query (jakarta.persistence.Query)2 ValueHolder (org.eclipse.persistence.indirection.ValueHolder)2 ValueHolderInterface (org.eclipse.persistence.indirection.ValueHolderInterface)2 JpaEntityManager (org.eclipse.persistence.jpa.JpaEntityManager)2 DatabaseQuery (org.eclipse.persistence.queries.DatabaseQuery)2 FetchGroup (org.eclipse.persistence.queries.FetchGroup)2 LoadGroup (org.eclipse.persistence.queries.LoadGroup)2 ReadAllQuery (org.eclipse.persistence.queries.ReadAllQuery)2 TypedQuery (jakarta.persistence.TypedQuery)1 Iterator (java.util.Iterator)1 Map (java.util.Map)1 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)1 IndirectList (org.eclipse.persistence.indirection.IndirectList)1 DescriptorIterator (org.eclipse.persistence.internal.descriptors.DescriptorIterator)1 DatabaseValueHolder (org.eclipse.persistence.internal.indirection.DatabaseValueHolder)1