Search in sources :

Example 1 with ElementContainerAdapter

use of org.datanucleus.store.types.ElementContainerAdapter in project datanucleus-core by datanucleus.

the class PersistFieldManager method processElementContainer.

private void processElementContainer(int fieldNumber, Object container, AbstractMemberMetaData mmd) {
    TypeManager typeManager = op.getExecutionContext().getTypeManager();
    ElementContainerHandler<Object, ElementContainerAdapter<Object>> elementContainerHandler = typeManager.getContainerHandler(mmd.getType());
    // Process all elements of the container that are PC
    ElementContainerAdapter containerAdapter = elementContainerHandler.getAdapter(container);
    ApiAdapter api = op.getExecutionContext().getApiAdapter();
    int objectType = elementContainerHandler.getObjectType(mmd);
    if (objectType == ObjectProvider.PC) {
        int elementPosition = 0;
        for (Object element : containerAdapter) {
            if (api.isPersistable(element)) {
                Object newElement = processPersistable(element, -1, objectType);
                ObjectProvider elementSM = op.getExecutionContext().findObjectProvider(newElement);
                if (elementSM.getReferencedPC() != null) {
                    // Must be attaching this element, so swap element (detached -> attached)
                    if (containerAdapter instanceof SequenceAdapter) {
                        ((SequenceAdapter) containerAdapter).update(newElement, elementPosition);
                    } else {
                        containerAdapter.remove(elementSM);
                        containerAdapter.add(newElement);
                    }
                }
            }
            elementPosition++;
        }
    } else {
        // Embedded/Serialized
        for (Object element : containerAdapter) {
            if (api.isPersistable(element)) {
                processPersistable(element, fieldNumber, objectType);
            }
        }
    }
}
Also used : ApiAdapter(org.datanucleus.api.ApiAdapter) ElementContainerAdapter(org.datanucleus.store.types.ElementContainerAdapter) SequenceAdapter(org.datanucleus.store.types.SequenceAdapter) TypeManager(org.datanucleus.store.types.TypeManager) ObjectProvider(org.datanucleus.state.ObjectProvider)

Example 2 with ElementContainerAdapter

use of org.datanucleus.store.types.ElementContainerAdapter in project datanucleus-core by datanucleus.

the class L2CachePopulateFieldManager method processElementContainer.

private void processElementContainer(int fieldNumber, Object container, AbstractMemberMetaData mmd, ElementContainerHandler<Object, ElementContainerAdapter<Object>> containerHandler) {
    RelationType relType = mmd.getRelationType(ec.getClassLoaderResolver());
    if (relType == RelationType.NONE) {
        // Container<Non-PC>
        boolean isContainerMutable = ec.getTypeManager().isSecondClassMutableType(mmd.getType().getName());
        String elementType = containerHandler.getElementTypeName(mmd.getContainer());
        boolean isElementMutable = ec.getTypeManager().isSecondClassMutableType(elementType);
        if (isContainerMutable || isElementMutable) {
            ElementContainerAdapter<Object> adapterToCache = containerHandler.getAdapter(newContainer(container, mmd, containerHandler));
            if (isElementMutable) {
                for (Object elementSCO : containerHandler.getAdapter(container)) {
                    adapterToCache.add(SCOUtils.copyValue(elementSCO));
                }
            } else {
                for (Object element : containerHandler.getAdapter(container)) {
                    adapterToCache.add(element);
                }
            }
            cachedPC.setFieldValue(fieldNumber, adapterToCache.getContainer());
        } else {
            // Both container and element are immutable so we can just cache it as it is
            cachedPC.setFieldValue(fieldNumber, container);
        }
    } else {
        // Container<PC>
        ElementContainerAdapter containerAdapter = containerHandler.getAdapter(container);
        if (containerAdapter instanceof SequenceAdapter && mmd.getOrderMetaData() != null && !mmd.getOrderMetaData().isIndexedList()) {
            // Ordered list so don't cache since dependent on datastore-retrieve order
            cachedPC.setLoadedField(fieldNumber, false);
            return;
        }
        try {
            // For arrays[PC] just use an Object array to store the ids because we can use the same type of the original container.
            // Later when restoring the values it will be based on the metadata instead of the actual container type, as opposed to how it's done for non-array containers.
            Object newContainer = mmd.hasArray() ? EMPTY_ARRAY : newContainer(container, mmd, containerHandler);
            ElementContainerAdapter containerToCacheAdapter = containerHandler.getAdapter(newContainer);
            ApiAdapter api = ec.getApiAdapter();
            if ((containerHandler.isSerialised(mmd) || containerHandler.isEmbedded(mmd)) && !ec.getNucleusContext().getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_CACHE_EMBEDDED)) {
                // User not caching embedded/serialised
                cachedPC.setLoadedField(fieldNumber, false);
                return;
            }
            for (Object element : containerAdapter) {
                if (containerHandler.isSerialised(mmd) || containerHandler.isEmbedded(mmd)) {
                    // Store embedded/serialised element as nested collection element
                    containerToCacheAdapter.add(convertPersistableToCachedPC(element));
                } else {
                    // Store id of element, since cached in its own right
                    containerToCacheAdapter.add(getCacheableIdForId(api, element));
                }
            }
            cachedPC.setFieldValue(fieldNumber, containerToCacheAdapter.getContainer());
        } catch (Exception e) {
            NucleusLogger.CACHE.warn("Unable to create object of type " + container.getClass().getName() + " for L2 caching : " + e.getMessage());
            // Contents not loaded so just mark as unloaded
            cachedPC.setLoadedField(fieldNumber, false);
        }
    }
}
Also used : ApiAdapter(org.datanucleus.api.ApiAdapter) ElementContainerAdapter(org.datanucleus.store.types.ElementContainerAdapter) RelationType(org.datanucleus.metadata.RelationType) SequenceAdapter(org.datanucleus.store.types.SequenceAdapter)

Example 3 with ElementContainerAdapter

use of org.datanucleus.store.types.ElementContainerAdapter in project datanucleus-core by datanucleus.

the class DeleteFieldManager method processSingleValue.

private void processSingleValue(Object value, AbstractMemberMetaData mmd, ExecutionContext ec, RelationType relationType) {
    // Process PC fields
    if (mmd.isDependent()) {
        processPersistable(value);
    } else if (manageRelationships && RelationType.isBidirectional(relationType) && !mmd.isEmbedded()) {
        ObjectProvider valueOP = ec.findObjectProvider(value);
        if (valueOP != null && !valueOP.getLifecycleState().isDeleted() && !valueOP.isDeleting()) {
            AbstractMemberMetaData relMmd = mmd.getRelatedMemberMetaData(ec.getClassLoaderResolver())[0];
            if (relationType == RelationType.ONE_TO_ONE_BI) {
                valueOP.replaceFieldMakeDirty(relMmd.getAbsoluteFieldNumber(), null);
                valueOP.flush();
            } else if (relationType == RelationType.MANY_TO_ONE_BI) {
                // Make sure field at other side is loaded, and remove from any Collection
                valueOP.loadField(relMmd.getAbsoluteFieldNumber());
                Object relValue = valueOP.provideField(relMmd.getAbsoluteFieldNumber());
                if (relValue != null) {
                    ContainerHandler containerHandler = ec.getTypeManager().getContainerHandler(relMmd.getType());
                    if (containerHandler instanceof ElementContainerHandler) {
                        ElementContainerAdapter adapter = (ElementContainerAdapter) containerHandler.getAdapter(relValue);
                        adapter.remove(op.getObject());
                    }
                }
            }
        }
    }
}
Also used : ElementContainerAdapter(org.datanucleus.store.types.ElementContainerAdapter) ContainerHandler(org.datanucleus.store.types.ContainerHandler) ElementContainerHandler(org.datanucleus.store.types.ElementContainerHandler) ObjectProvider(org.datanucleus.state.ObjectProvider) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) ElementContainerHandler(org.datanucleus.store.types.ElementContainerHandler)

Example 4 with ElementContainerAdapter

use of org.datanucleus.store.types.ElementContainerAdapter in project datanucleus-core by datanucleus.

the class DetachFieldManager method processElementContainer.

private Object processElementContainer(int fieldNumber, Object container, AbstractMemberMetaData mmd, ContainerHandler<Object, ElementContainerAdapter<Object>> containerHandler) {
    Object detachedContainer;
    // TODO If cascadeDetach is false then don't do this
    ElementContainerAdapter containerAdapter = containerHandler.getAdapter(container);
    if (copy) {
        detachedContainer = containerHandler.newContainer(mmd);
        ElementContainerAdapter<Object> copyAdapter = containerHandler.getAdapter(detachedContainer);
        for (Object element : containerAdapter) {
            copyAdapter.add(processPersistableCopy(element));
        }
        // Get the updated version of the container
        detachedContainer = copyAdapter.getContainer();
    } else {
        detachedContainer = container;
        for (Object element : containerAdapter) {
            processPersistable(element);
        }
    }
    return detachedContainer;
}
Also used : ElementContainerAdapter(org.datanucleus.store.types.ElementContainerAdapter)

Aggregations

ElementContainerAdapter (org.datanucleus.store.types.ElementContainerAdapter)4 ApiAdapter (org.datanucleus.api.ApiAdapter)2 ObjectProvider (org.datanucleus.state.ObjectProvider)2 SequenceAdapter (org.datanucleus.store.types.SequenceAdapter)2 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)1 RelationType (org.datanucleus.metadata.RelationType)1 ContainerHandler (org.datanucleus.store.types.ContainerHandler)1 ElementContainerHandler (org.datanucleus.store.types.ElementContainerHandler)1 TypeManager (org.datanucleus.store.types.TypeManager)1