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