use of org.datanucleus.store.types.scostore.ArrayStore in project datanucleus-rdbms by datanucleus.
the class ArrayMapping method postUpdate.
/**
* Method to be called after any update of the owner class element.
* This method could be called in two situations
* <ul>
* <li>Update an array field of an object by replacing the array with a new array,
* so UpdateRequest is called, which calls here</li>
* <li>Persist a new object, and it needed to wait til the element was inserted so
* goes into dirty state and then flush() triggers UpdateRequest, which comes here</li>
* </ul>
* @param ownerOP ObjectProvider of the owner
*/
public void postUpdate(ObjectProvider ownerOP) {
ExecutionContext ec = ownerOP.getExecutionContext();
Object value = ownerOP.provideField(getAbsoluteFieldNumber());
if (containerIsStoredInSingleColumn()) {
if (value != null) {
if (mmd.getArray().elementIsPersistent()) {
// Make sure all persistable elements have ObjectProviders
Object[] arrElements = (Object[]) value;
for (Object elem : arrElements) {
if (elem != null) {
ObjectProvider elemOP = ec.findObjectProvider(elem);
if (elemOP == null || ec.getApiAdapter().getExecutionContext(elem) == null) {
elemOP = ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, elem, false, ownerOP, mmd.getAbsoluteFieldNumber());
}
}
}
}
}
return;
}
if (value == null) {
// array is now null so remove any elements in the array
((ArrayStore) storeMgr.getBackingStoreForField(ec.getClassLoaderResolver(), mmd, null)).clear(ownerOP);
return;
}
if (!mmd.isCascadeUpdate()) {
// User doesn't want to update by reachability
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007008", mmd.getFullFieldName()));
}
return;
}
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007009", mmd.getFullFieldName()));
}
// Update the datastore
// TODO Do this more efficiently, removing elements no longer present, and adding new ones
ArrayStore backingStore = (ArrayStore) storeMgr.getBackingStoreForField(ec.getClassLoaderResolver(), mmd, null);
backingStore.clear(ownerOP);
backingStore.set(ownerOP, value);
}
use of org.datanucleus.store.types.scostore.ArrayStore in project datanucleus-rdbms by datanucleus.
the class ArrayMapping method postFetch.
/**
* Method to be called after any fetch of the owner class element.
* @param op ObjectProvider of the owner
*/
public void postFetch(ObjectProvider op) {
if (containerIsStoredInSingleColumn()) {
// Do nothing when stored in a single column since we are handled in the main request
return;
}
List elements = ((ArrayStore) storeMgr.getBackingStoreForField(op.getExecutionContext().getClassLoaderResolver(), mmd, null)).getArray(op);
if (elements != null) {
boolean primitiveArray = mmd.getType().getComponentType().isPrimitive();
Object array = Array.newInstance(mmd.getType().getComponentType(), elements.size());
for (int i = 0; i < elements.size(); i++) {
Object element = elements.get(i);
if (primitiveArray) {
// Handle the conversion back to the primitive
if (element instanceof Boolean) {
Array.setBoolean(array, i, ((Boolean) element).booleanValue());
} else if (element instanceof Byte) {
Array.setByte(array, i, ((Byte) element).byteValue());
} else if (element instanceof Character) {
Array.setChar(array, i, ((Character) element).charValue());
} else if (element instanceof Double) {
Array.setDouble(array, i, ((Double) element).doubleValue());
} else if (element instanceof Float) {
Array.setFloat(array, i, ((Float) element).floatValue());
} else if (element instanceof Integer) {
Array.setInt(array, i, ((Integer) element).intValue());
} else if (element instanceof Long) {
Array.setLong(array, i, ((Long) element).longValue());
} else if (element instanceof Short) {
Array.setShort(array, i, ((Short) element).shortValue());
}
} else {
Array.set(array, i, element);
}
}
if (elements.size() == 0) {
op.replaceFieldMakeDirty(getAbsoluteFieldNumber(), null);
} else {
op.replaceFieldMakeDirty(getAbsoluteFieldNumber(), array);
}
} else {
op.replaceFieldMakeDirty(getAbsoluteFieldNumber(), null);
}
}
use of org.datanucleus.store.types.scostore.ArrayStore in project datanucleus-rdbms by datanucleus.
the class ArrayMapping method postUpdate.
/**
* Method to be called after any update of the owner class element.
* This method could be called in two situations
* <ul>
* <li>Update an array field of an object by replacing the array with a new array,
* so UpdateRequest is called, which calls here</li>
* <li>Persist a new object, and it needed to wait til the element was inserted so
* goes into dirty state and then flush() triggers UpdateRequest, which comes here</li>
* </ul>
* @param ownerSM StateManager of the owner
*/
public void postUpdate(DNStateManager ownerSM) {
ExecutionContext ec = ownerSM.getExecutionContext();
Object value = ownerSM.provideField(getAbsoluteFieldNumber());
if (containerIsStoredInSingleColumn()) {
if (value != null) {
if (mmd.getArray().elementIsPersistent()) {
// Make sure all persistable elements have StateManagers
Object[] arrElements = (Object[]) value;
for (Object elem : arrElements) {
if (elem != null) {
DNStateManager elemSM = ec.findStateManager(elem);
if (elemSM == null || ec.getApiAdapter().getExecutionContext(elem) == null) {
elemSM = ec.getNucleusContext().getStateManagerFactory().newForEmbedded(ec, elem, false, ownerSM, mmd.getAbsoluteFieldNumber(), PersistableObjectType.EMBEDDED_ARRAY_ELEMENT_PC);
}
}
}
}
}
return;
}
if (value == null) {
// array is now null so remove any elements in the array
((ArrayStore) storeMgr.getBackingStoreForField(ec.getClassLoaderResolver(), mmd, null)).clear(ownerSM);
return;
}
if (!mmd.isCascadePersist()) {
// User doesn't want to update by reachability
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007008", IdentityUtils.getPersistableIdentityForId(ownerSM.getInternalObjectId()), mmd.getFullFieldName()));
}
return;
}
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007009", IdentityUtils.getPersistableIdentityForId(ownerSM.getInternalObjectId()), mmd.getFullFieldName()));
}
// Update the datastore
// TODO Do this more efficiently, removing elements no longer present, and adding new ones
ArrayStore backingStore = (ArrayStore) storeMgr.getBackingStoreForField(ec.getClassLoaderResolver(), mmd, null);
backingStore.clear(ownerSM);
backingStore.set(ownerSM, value);
}
use of org.datanucleus.store.types.scostore.ArrayStore in project datanucleus-rdbms by datanucleus.
the class ArrayMapping method postInsert.
// ---------------------- Implementation of MappingCallbacks ----------------------------------
/**
* Method to be called after the insert of the owner class element.
* @param ownerSM StateManager of the owner
*/
public void postInsert(DNStateManager ownerSM) {
ExecutionContext ec = ownerSM.getExecutionContext();
Object value = ownerSM.provideField(getAbsoluteFieldNumber());
if (value == null) {
return;
}
if (containerIsStoredInSingleColumn()) {
if (mmd.getArray().elementIsPersistent()) {
// Make sure all persistable elements have StateManagers
Object[] arrElements = (Object[]) value;
for (Object elem : arrElements) {
if (elem != null) {
DNStateManager elemSM = ec.findStateManager(elem);
if (elemSM == null || ec.getApiAdapter().getExecutionContext(elem) == null) {
elemSM = ec.getNucleusContext().getStateManagerFactory().newForEmbedded(ec, elem, false, ownerSM, mmd.getAbsoluteFieldNumber(), PersistableObjectType.EMBEDDED_ARRAY_ELEMENT_PC);
}
}
}
}
return;
}
int arrayLength = Array.getLength(value);
boolean persistentElements = (mmd.getRelationType(ec.getClassLoaderResolver()) != RelationType.NONE);
boolean needsAttaching = false;
if (persistentElements) {
Object[] array = (Object[]) value;
if (!mmd.isCascadePersist()) {
// Check that all elements are persistent before continuing and throw exception if necessary
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007006", mmd.getFullFieldName()));
}
for (int i = 0; i < arrayLength; i++) {
if (!ec.getApiAdapter().isDetached(array[i]) && !ec.getApiAdapter().isPersistent(array[i])) {
// Element is not persistent so throw exception
throw new ReachableObjectNotCascadedException(mmd.getFullFieldName(), array[i]);
}
}
} else {
// Reachability
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007007", IdentityUtils.getPersistableIdentityForId(ownerSM.getInternalObjectId()), mmd.getFullFieldName()));
}
}
for (int i = 0; i < arrayLength; i++) {
if (ec.getApiAdapter().isDetached(array[i])) {
needsAttaching = true;
break;
}
}
}
if (needsAttaching) {
// Create a wrapper and attach the elements (and add the others)
SCO collWrapper = replaceFieldWithWrapper(ownerSM, null);
if (arrayLength > 0) {
collWrapper.attachCopy(value);
// The attach will have put entries in the operationQueue if using optimistic, so flush them
ec.flushOperationsForBackingStore(((BackedSCO) collWrapper).getBackingStore(), ownerSM);
}
} else {
if (arrayLength > 0) {
// Add the elements direct to the datastore
((ArrayStore) storeMgr.getBackingStoreForField(ec.getClassLoaderResolver(), mmd, null)).set(ownerSM, value);
}
}
}
use of org.datanucleus.store.types.scostore.ArrayStore in project datanucleus-rdbms by datanucleus.
the class ArrayMapping method postInsert.
/**
* Method to be called after the insert of the owner class element.
* @param ownerOP ObjectProvider of the owner
*/
public void postInsert(ObjectProvider ownerOP) {
ExecutionContext ec = ownerOP.getExecutionContext();
Object value = ownerOP.provideField(getAbsoluteFieldNumber());
if (value == null) {
return;
}
if (containerIsStoredInSingleColumn()) {
if (mmd.getArray().elementIsPersistent()) {
// Make sure all persistable elements have ObjectProviders
Object[] arrElements = (Object[]) value;
for (Object elem : arrElements) {
if (elem != null) {
ObjectProvider elemOP = ec.findObjectProvider(elem);
if (elemOP == null || ec.getApiAdapter().getExecutionContext(elem) == null) {
elemOP = ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, elem, false, ownerOP, mmd.getAbsoluteFieldNumber());
}
}
}
}
return;
}
int arrayLength = Array.getLength(value);
boolean persistentElements = (mmd.getRelationType(ec.getClassLoaderResolver()) != RelationType.NONE);
boolean needsAttaching = false;
if (persistentElements) {
Object[] array = (Object[]) value;
if (!mmd.isCascadePersist()) {
// Check that all elements are persistent before continuing and throw exception if necessary
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007006", mmd.getFullFieldName()));
}
for (int i = 0; i < arrayLength; i++) {
if (!ec.getApiAdapter().isDetached(array[i]) && !ec.getApiAdapter().isPersistent(array[i])) {
// Element is not persistent so throw exception
throw new ReachableObjectNotCascadedException(mmd.getFullFieldName(), array[i]);
}
}
} else {
// Reachability
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007007", mmd.getFullFieldName()));
}
}
for (int i = 0; i < arrayLength; i++) {
if (ownerOP.getExecutionContext().getApiAdapter().isDetached(array[i])) {
needsAttaching = true;
break;
}
}
}
if (needsAttaching) {
// Create a wrapper and attach the elements (and add the others)
SCO collWrapper = replaceFieldWithWrapper(ownerOP, null);
if (arrayLength > 0) {
collWrapper.attachCopy(value);
// The attach will have put entries in the operationQueue if using optimistic, so flush them
ownerOP.getExecutionContext().flushOperationsForBackingStore(((BackedSCO) collWrapper).getBackingStore(), ownerOP);
}
} else {
if (arrayLength > 0) {
// Add the elements direct to the datastore
((ArrayStore) storeMgr.getBackingStoreForField(ownerOP.getExecutionContext().getClassLoaderResolver(), mmd, null)).set(ownerOP, value);
}
}
}
Aggregations