Search in sources :

Example 46 with ApiAdapter

use of org.datanucleus.api.ApiAdapter in project datanucleus-core by datanucleus.

the class L2CachePopulateFieldManager method processMapContainer.

private void processMapContainer(int fieldNumber, Object mapContainer, AbstractMemberMetaData mmd, MapHandler<Object> containerHandler) {
    try {
        if (!ec.getNucleusContext().getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_CACHE_EMBEDDED)) {
            RelationType relType = mmd.getRelationType(ec.getClassLoaderResolver());
            if (relType != RelationType.NONE && (containerHandler.isSerialised(mmd) || containerHandler.isEmbedded(mmd))) {
                // User has requested no caching of embedded/serialised, so ignore this field
                cachedPC.setLoadedField(fieldNumber, false);
                return;
            }
        }
        boolean keyIsPersistent = mmd.getMap().keyIsPersistent();
        boolean keyIsEmbedded = mmd.getMap().isEmbeddedKey();
        boolean keyIsSerialised = mmd.getMap().isSerializedKey();
        boolean valueIsPersistent = mmd.getMap().valueIsPersistent();
        boolean valueIsEmbedded = mmd.getMap().isEmbeddedValue();
        boolean valueIsSerialised = mmd.getMap().isSerializedValue();
        Object newContainer = newContainer(mapContainer, mmd, containerHandler);
        MapContainerAdapter<Object> mapToCacheAdapter = containerHandler.getAdapter(newContainer);
        ApiAdapter api = ec.getApiAdapter();
        for (Entry<Object, Object> entry : containerHandler.getAdapter(mapContainer).entries()) {
            Object mapKey = null;
            if (keyIsPersistent) {
                mapKey = (keyIsEmbedded || keyIsSerialised || mmd.isSerialized()) ? convertPersistableToCachedPC(entry.getKey()) : getCacheableIdForId(api, entry.getKey());
            } else {
                mapKey = SCOUtils.copyValue(entry.getKey());
            }
            Object mapValue = null;
            if (valueIsPersistent) {
                mapValue = (valueIsEmbedded || valueIsSerialised || mmd.isSerialized()) ? convertPersistableToCachedPC(entry.getValue()) : getCacheableIdForId(api, entry.getValue());
            } else {
                mapValue = SCOUtils.copyValue(entry.getValue());
            }
            mapToCacheAdapter.put(mapKey, mapValue);
        }
        // Put Map<X, Y> in CachedPC where X, Y can be OID or CachedPC if they are persistable objects
        cachedPC.setFieldValue(fieldNumber, mapToCacheAdapter.getContainer());
    } catch (Exception e) {
        NucleusLogger.CACHE.warn("Unable to create object of type " + mapContainer.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) RelationType(org.datanucleus.metadata.RelationType)

Example 47 with ApiAdapter

use of org.datanucleus.api.ApiAdapter 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 48 with ApiAdapter

use of org.datanucleus.api.ApiAdapter in project datanucleus-core by datanucleus.

the class SCOUtils method attachCopyForMap.

/**
 * Method to return an attached copy of the passed (detached) value. The returned attached copy is a SCO
 * wrapper. Goes through the existing elements in the store for this owner field and removes ones no
 * longer present, and adds new elements. All elements in the (detached) value are attached.
 * @param ownerOP ObjectProvider for the owning object with the map
 * @param detachedEntries The detached entries in the map
 * @param attached Map to add the attached copies to
 * @param keysWithoutIdentity Whether the keys have their own identity
 * @param valuesWithoutIdentity Whether the values have their own identity
 */
public static void attachCopyForMap(ObjectProvider ownerOP, Set detachedEntries, Map attached, boolean keysWithoutIdentity, boolean valuesWithoutIdentity) {
    Iterator iter = detachedEntries.iterator();
    ApiAdapter api = ownerOP.getExecutionContext().getApiAdapter();
    while (iter.hasNext()) {
        Map.Entry entry = (Map.Entry) iter.next();
        Object val = entry.getValue();
        Object key = entry.getKey();
        if (api.isPersistable(val) && api.isDetachable(val)) {
            val = ownerOP.getExecutionContext().attachObjectCopy(ownerOP, val, valuesWithoutIdentity);
        }
        if (api.isPersistable(key) && api.isDetachable(key)) {
            key = ownerOP.getExecutionContext().attachObjectCopy(ownerOP, key, keysWithoutIdentity);
        }
        attached.put(key, val);
    }
}
Also used : ApiAdapter(org.datanucleus.api.ApiAdapter) Iterator(java.util.Iterator) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap)

Example 49 with ApiAdapter

use of org.datanucleus.api.ApiAdapter in project datanucleus-core by datanucleus.

the class SCOUtils method detachCopyForMap.

/**
 * Convenience method to detach copies (recursively) of all elements for a map field. All elements that
 * are persistable will be detached.
 * @param ownerOP ObjectProvider for the owning object with the map
 * @param entries The entries in the map
 * @param state FetchPlan state
 * @param detached Map to add the detached copies to
 */
public static void detachCopyForMap(ObjectProvider ownerOP, Set entries, FetchPlanState state, Map detached) {
    ApiAdapter api = ownerOP.getExecutionContext().getApiAdapter();
    for (Iterator it = entries.iterator(); it.hasNext(); ) {
        Map.Entry entry = (Map.Entry) it.next();
        Object val = entry.getValue();
        Object key = entry.getKey();
        if (api.isPersistable(val)) {
            val = ownerOP.getExecutionContext().detachObjectCopy(state, val);
        }
        if (api.isPersistable(key)) {
            key = ownerOP.getExecutionContext().detachObjectCopy(state, key);
        }
        detached.put(key, val);
    }
}
Also used : ApiAdapter(org.datanucleus.api.ApiAdapter) Iterator(java.util.Iterator) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap)

Example 50 with ApiAdapter

use of org.datanucleus.api.ApiAdapter in project datanucleus-core by datanucleus.

the class SCOUtils method arrayIsStoredInSingleColumn.

/**
 * Convenience method to return if an array field has the elements stored into the table of the field as a
 * single (BLOB) column.
 * @param fmd MetaData for the field
 * @param mmgr MetaData manager
 * @return Whether the elements are stored in a single column
 */
public static boolean arrayIsStoredInSingleColumn(AbstractMemberMetaData fmd, MetaDataManager mmgr) {
    boolean singleColumn = fmd.isSerialized();
    if (!singleColumn && fmd.getArray() != null && fmd.getJoinMetaData() == null) {
        if (fmd.getArray().isEmbeddedElement()) {
            // Elements are embedded but no join table so we store in a single column
            singleColumn = true;
        }
        Class elementClass = fmd.getType().getComponentType();
        ApiAdapter api = mmgr.getApiAdapter();
        if (!elementClass.isInterface() && !api.isPersistable(elementClass)) {
            // Array of non-PC with no join table so store in single column of main table
            singleColumn = true;
        }
    }
    return singleColumn;
}
Also used : ApiAdapter(org.datanucleus.api.ApiAdapter)

Aggregations

ApiAdapter (org.datanucleus.api.ApiAdapter)53 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)19 ObjectProvider (org.datanucleus.state.ObjectProvider)16 ExecutionContext (org.datanucleus.ExecutionContext)12 Map (java.util.Map)11 NucleusException (org.datanucleus.exceptions.NucleusException)11 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)10 Iterator (java.util.Iterator)8 NucleusObjectNotFoundException (org.datanucleus.exceptions.NucleusObjectNotFoundException)8 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)8 Collection (java.util.Collection)7 HashMap (java.util.HashMap)7 RelationType (org.datanucleus.metadata.RelationType)7 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)7 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)6 ClassNotResolvedException (org.datanucleus.exceptions.ClassNotResolvedException)6 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)5 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)5 TypeManager (org.datanucleus.store.types.TypeManager)5 SortedMap (java.util.SortedMap)4