Search in sources :

Example 1 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class TestService method testMarshallBid.

@Test
public void testMarshallBid() throws Exception {
    PersistenceResource resource = new PersistenceResource();
    resource.setPersistenceFactory(factory);
    PersistenceContext context = getAuctionPersistenceContext(null);
    DynamicEntity entity1 = context.newEntity("Auction");
    entity1.set("name", "Computer");
    DynamicEntity entity2 = context.newEntity("User");
    entity2.set("name", "Bob");
    context.create(null, entity2);
    DynamicEntity entity3 = context.newEntity("Bid");
    entity3.set("amount", 200d);
    entity3.set("user", entity2);
    entity3.set("auction", entity1);
    context.create(null, entity3);
    InputStream stream = serializeToStream(entity3, context, MediaType.APPLICATION_JSON_TYPE);
    try {
        entity3 = (DynamicEntity) context.unmarshalEntity("Bid", MediaType.APPLICATION_JSON_TYPE, stream);
    } catch (JAXBException e) {
        fail("Exception unmarsalling: " + e);
    }
    (new FetchGroupManager()).setObjectFetchGroup(entity3, null, null);
    entity1 = entity3.get("auction");
    assertNotNull("Name of auction is null.", entity1.get("name"));
    assertTrue("Name of auction is incorrect.", entity1.get("name").equals("Computer"));
}
Also used : PersistenceResource(org.eclipse.persistence.jpa.rs.resources.unversioned.PersistenceResource) FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) DynamicEntity(org.eclipse.persistence.dynamic.DynamicEntity) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) JAXBException(jakarta.xml.bind.JAXBException) PersistenceContext(org.eclipse.persistence.jpa.rs.PersistenceContext) Test(org.junit.Test)

Example 2 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class TestServiceNonRelational method testMarshallZips.

@SuppressWarnings("rawtypes")
@Test
public void testMarshallZips() throws Exception {
    setContext(ZIPS_PU);
    PersistenceResource resource = new PersistenceResource();
    resource.setPersistenceFactory(factory);
    DynamicEntity zips = context.newEntity("Zips");
    zips.set("state", "ON");
    zips.set("city", "Ottawa");
    zips.set("pop", 6055);
    zips.set("id", "1234");
    List<Double> loc = new ArrayList<>();
    loc.add(45.4214);
    loc.add(75.6919);
    zips.set("loc", loc);
    context.create(null, zips);
    InputStream stream = serializeToStream(zips, context, MediaType.APPLICATION_XML_TYPE);
    zips = (DynamicEntity) context.unmarshalEntity("Zips", MediaType.APPLICATION_XML_TYPE, stream);
    (new FetchGroupManager()).setObjectFetchGroup(zips, null, null);
    String state = zips.get("state");
    assertNotNull("State of place is null.", state);
    assertTrue("ON".equals(state));
    String id = zips.get("id");
    assertNotNull("id is null.", id);
    assertTrue("1234".equals(id));
    assertTrue("Unexpected number of objects in loc", (((Collection) zips.get("loc")).size() == 2));
}
Also used : PersistenceResource(org.eclipse.persistence.jpa.rs.resources.unversioned.PersistenceResource) FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) DynamicEntity(org.eclipse.persistence.dynamic.DynamicEntity) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Example 3 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class TestServiceNonRelational method testMarshallPerson.

@Test
public void testMarshallPerson() throws Exception {
    setContext(PERSON_PU);
    PersistenceResource resource = new PersistenceResource();
    resource.setPersistenceFactory(factory);
    DynamicEntity person = context.newEntity("Person");
    person.set("firstName", "Jim");
    person.set("lastName", "Smith");
    person.set("age", 48);
    person.set("occupation", "Engineer");
    person.set("currentEmployer", "Oracle");
    List<String> pastEmployers = new ArrayList<>();
    pastEmployers.add("BEA");
    pastEmployers.add("IBM");
    pastEmployers.add("Sun");
    person.set("pastEmployers", pastEmployers);
    DynamicEntity address1 = context.newEntity("Addresses");
    address1.set("street1", "123 Sandy Lane");
    address1.set("city", "San Jose");
    address1.set("state", "CA");
    address1.set("zip", 94143);
    DynamicEntity address2 = context.newEntity("Addresses");
    address2.set("street1", "334 California Street");
    address2.set("city", "San Francisco");
    address2.set("state", "CA");
    address2.set("zip", 94110);
    List<Object> addresses = new ArrayList<>();
    addresses.add(address1);
    addresses.add(address2);
    person.set("addresses", addresses);
    context.create(null, person);
    InputStream stream = serializeToStream(person, context, MediaType.APPLICATION_XML_TYPE);
    person = (DynamicEntity) context.unmarshalEntity("Person", MediaType.APPLICATION_XML_TYPE, stream);
    (new FetchGroupManager()).setObjectFetchGroup(person, null, null);
    String firstName = person.get("firstName");
    assertNotNull("firstName is null.", firstName);
    assertTrue("Jim".equals(firstName));
}
Also used : PersistenceResource(org.eclipse.persistence.jpa.rs.resources.unversioned.PersistenceResource) FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) DynamicEntity(org.eclipse.persistence.dynamic.DynamicEntity) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Example 4 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class TestServiceNonRelational method testMarshallPlace.

@Test
public void testMarshallPlace() throws Exception {
    setContext(PLACE_PU);
    PersistenceResource resource = new PersistenceResource();
    resource.setPersistenceFactory(factory);
    DynamicEntity place = context.newEntity("Place");
    place.set("state", "Ontario");
    context.create(null, place);
    InputStream stream = serializeToStream(place, context, MediaType.APPLICATION_JSON_TYPE);
    place = (DynamicEntity) context.unmarshalEntity("Place", MediaType.APPLICATION_JSON_TYPE, stream);
    (new FetchGroupManager()).setObjectFetchGroup(place, null, null);
    String state = place.get("state");
    assertNotNull("State of place is null.", state);
    assertTrue("Ontario".equals(state));
}
Also used : PersistenceResource(org.eclipse.persistence.jpa.rs.resources.unversioned.PersistenceResource) FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) DynamicEntity(org.eclipse.persistence.dynamic.DynamicEntity) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Test(org.junit.Test)

Example 5 with FetchGroupManager

use of org.eclipse.persistence.descriptors.FetchGroupManager in project eclipselink by eclipse-ee4j.

the class ObjectBuilder method buildWorkingCopyCloneFromRow.

/**
 * INTERNAL:
 * Builds a working copy clone directly from the database row.
 * This is the key method that allows us to execute queries against a
 * UnitOfWork while in transaction and not cache the results in the shared
 * cache.  This is because we might violate transaction isolation by
 * putting uncommitted versions of objects in the shared cache.
 */
protected Object buildWorkingCopyCloneFromRow(ObjectBuildingQuery query, JoinedAttributeManager joinManager, AbstractRecord databaseRow, UnitOfWorkImpl unitOfWork, Object primaryKey, CacheKey preFetchedCacheKey) throws DatabaseException, QueryException {
    ClassDescriptor descriptor = this.descriptor;
    // If the clone already exists then it may only need to be refreshed or returned.
    // We call directly on the identity map to avoid going to the parent,
    // registering if found, and wrapping the result.
    // Acquire or create the cache key as is need once the object is build anyway.
    CacheKey unitOfWorkCacheKey = unitOfWork.getIdentityMapAccessorInstance().getIdentityMapManager().acquireLock(primaryKey, descriptor.getJavaClass(), false, descriptor, true);
    Object workingClone = unitOfWorkCacheKey.getObject();
    FetchGroup fetchGroup = query.getExecutionFetchGroup(descriptor);
    FetchGroupManager fetchGroupManager = descriptor.getFetchGroupManager();
    try {
        // If there is a clone, and it is not a refresh then just return it.
        boolean wasAClone = workingClone != null;
        boolean isARefresh = query.shouldRefreshIdentityMapResult() || (query.isLockQuery() && (!wasAClone || !query.isClonePessimisticLocked(workingClone, unitOfWork)));
        // Also need to refresh if the clone is a partial object and query requires more than its fetch group.
        if (wasAClone && fetchGroupManager != null && (fetchGroupManager.isPartialObject(workingClone) && (!fetchGroupManager.isObjectValidForFetchGroup(workingClone, fetchGroupManager.getEntityFetchGroup(fetchGroup))))) {
            isARefresh = true;
        }
        if (wasAClone && (!isARefresh)) {
            return workingClone;
        }
        boolean wasAnOriginal = false;
        boolean isIsolated = descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() || (descriptor.shouldIsolateObjectsInUnitOfWorkEarlyTransaction() && unitOfWork.wasTransactionBegunPrematurely());
        Object original = null;
        CacheKey originalCacheKey = null;
        // If not refreshing can get the object from the cache.
        if ((!isARefresh) && (!isIsolated) && !query.shouldRetrieveBypassCache() && !unitOfWork.shouldReadFromDB() && (!unitOfWork.shouldForceReadFromDB(query, primaryKey))) {
            AbstractSession session = unitOfWork.getParentIdentityMapSession(query);
            if (preFetchedCacheKey == null) {
                originalCacheKey = session.getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey, descriptor.getJavaClass(), descriptor, false);
            } else {
                originalCacheKey = preFetchedCacheKey;
                originalCacheKey.acquireLock(query);
            }
            if (originalCacheKey != null) {
                // PERF: Read-lock is not required on object as unit of work will acquire this on clone and object cannot gc and object identity is maintained.
                original = originalCacheKey.getObject();
                wasAnOriginal = original != null;
                // If the original is invalid or always refresh then need to refresh.
                isARefresh = wasAnOriginal && (descriptor.shouldAlwaysRefreshCache() || descriptor.getCacheInvalidationPolicy().isInvalidated(originalCacheKey, query.getExecutionTime()));
                // Otherwise can just register the cached original object and return it.
                if (wasAnOriginal && (!isARefresh)) {
                    if (descriptor.getCachePolicy().isSharedIsolation() || !descriptor.shouldIsolateProtectedObjectsInUnitOfWork()) {
                        // or using protected isolation and isolated client sessions
                        return unitOfWork.cloneAndRegisterObject(original, originalCacheKey, unitOfWorkCacheKey, descriptor);
                    }
                }
            }
        }
        if (!wasAClone) {
            // The copy policy is easier to invoke if we have an original.
            if (wasAnOriginal && !query.shouldRetrieveBypassCache()) {
                workingClone = instantiateWorkingCopyClone(original, unitOfWork);
                // intentionally put nothing in clones to originals, unless really was one.
                unitOfWork.getCloneToOriginals().put(workingClone, original);
            } else {
                if (descriptor.hasSerializedObjectPolicy() && query.shouldUseSerializedObjectPolicy() && !databaseRow.hasSopObject()) {
                    // serialized sopObject is a value corresponding to sopField in the row, row.sopObject==null;
                    // the following line sets deserialized sopObject into row.sopObject variable and sets sopField's value to null;
                    workingClone = descriptor.getSerializedObjectPolicy().getObjectFromRow(databaseRow, unitOfWork, (ObjectLevelReadQuery) query);
                }
                if (workingClone == null) {
                    // What happens if a copy policy is defined is not pleasant.
                    // workingClone = instantiateWorkingCopyCloneFromRow(databaseRow, query, primaryKey, unitOfWork);
                    // Create a new instance instead. The object is populated later by buildAttributesIntoWorkingCopyClone method.
                    workingClone = buildNewInstance();
                }
            }
            // This must be registered before it is built to avoid cycles.
            // The version and read is set below in copyQueryInfoToCacheKey.
            unitOfWorkCacheKey.setObject(workingClone);
            // This must be registered before it is built to avoid cycles.
            unitOfWork.getCloneMapping().put(workingClone, workingClone);
        }
        // Must avoid infinite loops while refreshing.
        if (wasAClone && (unitOfWorkCacheKey.getLastUpdatedQueryId() >= query.getQueryId())) {
            return workingClone;
        }
        copyQueryInfoToCacheKey(unitOfWorkCacheKey, query, databaseRow, unitOfWork, descriptor);
        ObjectChangePolicy policy = descriptor.getObjectChangePolicy();
        // If it was a clone the change listener must be cleared after.
        if (!wasAClone) {
            // The change listener must be set before building the clone as aggregate/collections need the listener.
            policy.setChangeListener(workingClone, unitOfWork, descriptor);
        }
        // Turn it 'off' to prevent unwanted events.
        policy.dissableEventProcessing(workingClone);
        if (isARefresh && fetchGroupManager != null) {
            fetchGroupManager.setObjectFetchGroup(workingClone, query.getExecutionFetchGroup(this.descriptor), unitOfWork);
        }
        if (!unitOfWork.wasTransactionBegunPrematurely() && descriptor.getCachePolicy().isProtectedIsolation() && !isIsolated && !query.shouldStoreBypassCache()) {
            // we are at this point because we have isolated protected entities to the UnitOfWork
            // we should ensure that we populate the cache as well.
            originalCacheKey = (CacheKey) buildObject(true, query, databaseRow, unitOfWork.getParentIdentityMapSession(descriptor, false, true), primaryKey, preFetchedCacheKey, descriptor, joinManager);
        }
        // the cachekey will be null so the attribute building will not be able to access the shared cache.
        if (isARefresh) {
            // if we need to refresh the UOW then remove the cache key and the clone will be rebuilt not using any of the
            // cache.  This should be updated to force the buildAttributesIntoWorkingCopyClone to refresh the objects
            originalCacheKey = null;
        }
        // Build/refresh the clone from the row.
        buildAttributesIntoWorkingCopyClone(workingClone, originalCacheKey, query, joinManager, databaseRow, unitOfWork, wasAClone);
        // Set fetch group after building object if not a refresh to avoid checking fetch during building.
        if ((!isARefresh) && fetchGroupManager != null) {
            if (wasAnOriginal) {
                // 485984: Save the FetchGroup from the original
                fetchGroupManager.setObjectFetchGroup(workingClone, fetchGroupManager.getObjectFetchGroup(original), unitOfWork);
            } else {
                fetchGroupManager.setObjectFetchGroup(workingClone, query.getExecutionFetchGroup(this.descriptor), unitOfWork);
            }
        }
        Object backupClone = policy.buildBackupClone(workingClone, this, unitOfWork);
        // If it was a clone the change listener must be cleared.
        if (wasAClone) {
            policy.clearChanges(workingClone, unitOfWork, descriptor, isARefresh);
        }
        policy.enableEventProcessing(workingClone);
        unitOfWork.getCloneMapping().put(workingClone, backupClone);
        query.recordCloneForPessimisticLocking(workingClone, unitOfWork);
        // PERF: Cache the primary key if implements PersistenceEntity.
        if (workingClone instanceof PersistenceEntity) {
            ((PersistenceEntity) workingClone)._persistence_setId(primaryKey);
        }
    } finally {
        unitOfWorkCacheKey.release();
    }
    instantiateEagerMappings(workingClone, unitOfWork);
    return workingClone;
}
Also used : ObjectLevelReadQuery(org.eclipse.persistence.queries.ObjectLevelReadQuery) FetchGroupManager(org.eclipse.persistence.descriptors.FetchGroupManager) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) ObjectChangePolicy(org.eclipse.persistence.descriptors.changetracking.ObjectChangePolicy) FetchGroup(org.eclipse.persistence.queries.FetchGroup) EntityFetchGroup(org.eclipse.persistence.internal.queries.EntityFetchGroup) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) CacheKey(org.eclipse.persistence.internal.identitymaps.CacheKey) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Aggregations

FetchGroupManager (org.eclipse.persistence.descriptors.FetchGroupManager)27 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)13 FetchGroup (org.eclipse.persistence.queries.FetchGroup)12 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)8 EntityFetchGroup (org.eclipse.persistence.internal.queries.EntityFetchGroup)8 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)6 ByteArrayInputStream (java.io.ByteArrayInputStream)4 InputStream (java.io.InputStream)4 DynamicEntity (org.eclipse.persistence.dynamic.DynamicEntity)4 CacheKey (org.eclipse.persistence.internal.identitymaps.CacheKey)4 PersistenceResource (org.eclipse.persistence.jpa.rs.resources.unversioned.PersistenceResource)4 Test (org.junit.Test)4 FetchGroupTracker (org.eclipse.persistence.queries.FetchGroupTracker)3 ArrayList (java.util.ArrayList)2 Vector (java.util.Vector)2 DescriptorEvent (org.eclipse.persistence.descriptors.DescriptorEvent)2 XMLInverseReferenceMapping (org.eclipse.persistence.oxm.mappings.XMLInverseReferenceMapping)2 ObjectLevelReadQuery (org.eclipse.persistence.queries.ObjectLevelReadQuery)2 ReadAllQuery (org.eclipse.persistence.queries.ReadAllQuery)2 JAXBException (jakarta.xml.bind.JAXBException)1