Search in sources :

Example 1 with ArrayStore

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);
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) ObjectProvider(org.datanucleus.state.ObjectProvider) ArrayStore(org.datanucleus.store.types.scostore.ArrayStore)

Example 2 with ArrayStore

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);
    }
}
Also used : ArrayStore(org.datanucleus.store.types.scostore.ArrayStore) List(java.util.List)

Example 3 with ArrayStore

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);
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) DNStateManager(org.datanucleus.state.DNStateManager) ArrayStore(org.datanucleus.store.types.scostore.ArrayStore)

Example 4 with ArrayStore

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);
        }
    }
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) DNStateManager(org.datanucleus.state.DNStateManager) ArrayStore(org.datanucleus.store.types.scostore.ArrayStore) SCO(org.datanucleus.store.types.SCO) BackedSCO(org.datanucleus.store.types.wrappers.backed.BackedSCO) ReachableObjectNotCascadedException(org.datanucleus.exceptions.ReachableObjectNotCascadedException)

Example 5 with ArrayStore

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);
        }
    }
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) ObjectProvider(org.datanucleus.state.ObjectProvider) ArrayStore(org.datanucleus.store.types.scostore.ArrayStore) SCO(org.datanucleus.store.types.SCO) BackedSCO(org.datanucleus.store.types.wrappers.backed.BackedSCO) ReachableObjectNotCascadedException(org.datanucleus.exceptions.ReachableObjectNotCascadedException)

Aggregations

ArrayStore (org.datanucleus.store.types.scostore.ArrayStore)8 ExecutionContext (org.datanucleus.ExecutionContext)4 List (java.util.List)2 ReachableObjectNotCascadedException (org.datanucleus.exceptions.ReachableObjectNotCascadedException)2 DNStateManager (org.datanucleus.state.DNStateManager)2 ObjectProvider (org.datanucleus.state.ObjectProvider)2 SCO (org.datanucleus.store.types.SCO)2 BackedSCO (org.datanucleus.store.types.wrappers.backed.BackedSCO)2