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);
}
}
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);
}
}
}
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);
}
}
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);
}
}
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;
}
Aggregations