Search in sources :

Example 91 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.

the class PersistableMapping method postUpdate.

/**
 * Method executed just afer any update of the owning object, allowing any necessary action to this field and the object stored in it.
 * @param op ObjectProvider for the owner
 */
public void postUpdate(ObjectProvider op) {
    Object pc = op.provideField(mmd.getAbsoluteFieldNumber());
    pc = mmd.isSingleCollection() ? SCOUtils.singleCollectionValue(getStoreManager().getNucleusContext().getTypeManager(), pc) : pc;
    ClassLoaderResolver clr = op.getExecutionContext().getClassLoaderResolver();
    RelationType relationType = mmd.getRelationType(clr);
    if (pc == null) {
        if (relationType == RelationType.MANY_TO_ONE_UNI) {
            // Update join table entry
            PersistableRelationStore store = (PersistableRelationStore) storeMgr.getBackingStoreForField(clr, mmd, mmd.getType());
            store.remove(op);
        }
        return;
    }
    ObjectProvider otherOP = op.getExecutionContext().findObjectProvider(pc);
    if (otherOP == null) {
        if (relationType == RelationType.ONE_TO_ONE_BI || relationType == RelationType.MANY_TO_ONE_BI || relationType == RelationType.MANY_TO_ONE_UNI) {
            // Related object is not yet persisted (e.g 1-1 with FK at other side) so persist it
            Object other = op.getExecutionContext().persistObjectInternal(pc, null, -1, ObjectProvider.PC);
            otherOP = op.getExecutionContext().findObjectProvider(other);
        }
    }
    if (relationType == RelationType.MANY_TO_ONE_UNI) {
        // Update join table entry
        PersistableRelationStore store = (PersistableRelationStore) storeMgr.getBackingStoreForField(clr, mmd, mmd.getType());
        store.update(op, otherOP);
    }
}
Also used : RelationType(org.datanucleus.metadata.RelationType) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) ObjectProvider(org.datanucleus.state.ObjectProvider) PersistableRelationStore(org.datanucleus.store.types.scostore.PersistableRelationStore)

Example 92 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.

the class ReferenceMapping method getReferenceStringForObject.

/**
 * Method to convert an object to be stored into a "reference string" to store.
 * Reference string is of the form :
 * <ul>
 * <li>ID_MAPPING : "{classname}:{id}"</li>
 * <li>XCALIA_MAPPING (datastore-id) : "{definer}:{id-key}" where definer is discriminator/classname</li>
 * <li>XCALIA_MAPPING (app-id) : "{definer}:{id}" where definer is discriminator/classname</li>
 * </ul>
 * @param ec ExecutionContext
 * @param value The object
 * @return The reference string
 */
protected String getReferenceStringForObject(ExecutionContext ec, Object value) {
    if (ec.getApiAdapter().isPersistable(value)) {
        ObjectProvider op = ec.findObjectProvider(value);
        if (op == null) {
            // Referenced object is not yet persistent, so persist it
            ec.persistObjectInternal(value, null, -1, ObjectProvider.PC);
            op = ec.findObjectProvider(value);
            // Make sure the object is in the datastore so the id is set
            op.flush();
        }
        String refString = null;
        if (mappingStrategy == ID_MAPPING) {
            refString = value.getClass().getName() + ":" + op.getInternalObjectId();
        } else if (mappingStrategy == XCALIA_MAPPING) {
            AbstractClassMetaData cmd = op.getClassMetaData();
            DiscriminatorMetaData dismd = cmd.getDiscriminatorMetaData();
            String definer = null;
            if (dismd != null && dismd.getValue() != null) {
                definer = dismd.getValue();
            } else {
                definer = cmd.getFullClassName();
            }
            if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                refString = definer + ":" + IdentityUtils.getTargetKeyForDatastoreIdentity(op.getInternalObjectId());
            } else {
                refString = definer + ":" + op.getInternalObjectId().toString();
            }
        }
        return refString;
    }
    // Cater for non-persistable objects
    throw new NucleusException("Identity mapping of non-persistable interface/Object fields not supported");
}
Also used : DiscriminatorMetaData(org.datanucleus.metadata.DiscriminatorMetaData) ObjectProvider(org.datanucleus.state.ObjectProvider) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 93 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.

the class ForwardQueryResult method nextResultSetElement.

/**
 * Accessor for the next object from the ResultSet.
 * @return The next element from the ResultSet.
 */
protected E nextResultSetElement() {
    if (rof == null) {
        // Already disconnected
        return null;
    }
    // Convert this row into its associated object and save it
    E nextElement = rof.getObject();
    JDBCUtils.logWarnings(rs);
    resultObjs.add(nextElement);
    if (resultIds != null) {
        resultIds.add(api.getIdForObject(nextElement));
    }
    // Process any bulk loaded members
    if (bulkLoadedValueByMemberNumber != null) {
        Map<Integer, Object> memberValues = bulkLoadedValueByMemberNumber.get(api.getIdForObject(nextElement));
        if (memberValues != null) {
            ObjectProvider op = query.getExecutionContext().findObjectProvider(nextElement);
            Iterator<Map.Entry<Integer, Object>> memberValIter = memberValues.entrySet().iterator();
            while (memberValIter.hasNext()) {
                Map.Entry<Integer, Object> memberValueEntry = memberValIter.next();
                op.replaceField(memberValueEntry.getKey(), memberValueEntry.getValue());
            }
            op.replaceAllLoadedSCOFieldsWithWrappers();
        }
    }
    // Update the status of whether there are more results outstanding
    if (rs == null) {
        throw new NucleusUserException("Results for query have already been closed. Perhaps you called flush(), closed the query, or ended a transaction");
    }
    try {
        moreResultSetRows = rs.next();
        if (applyRangeChecks) {
            // Check if we have reached the end of the range
            int maxElements = (int) (query.getRangeToExcl() - query.getRangeFromIncl());
            if (resultObjs.size() == maxElements) {
                moreResultSetRows = false;
            }
        }
        if (!moreResultSetRows) {
            closeResults();
        }
    } catch (SQLException e) {
        throw api.getDataStoreExceptionForException(Localiser.msg("052601", e.getMessage()), e);
    }
    return nextElement;
}
Also used : SQLException(java.sql.SQLException) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ObjectProvider(org.datanucleus.state.ObjectProvider) Map(java.util.Map)

Example 94 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.

the class CollectionMapping 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();
    Collection value = (Collection) ownerOP.provideField(getAbsoluteFieldNumber());
    if (containerIsStoredInSingleColumn()) {
        if (value != null) {
            if (mmd.getCollection().elementIsPersistent()) {
                // Make sure all persistable elements have ObjectProviders
                Object[] collElements = value.toArray();
                for (Object elem : collElements) {
                    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) {
        // replace null collections with an empty SCO wrapper
        replaceFieldWithWrapper(ownerOP, null);
        return;
    }
    Object[] collElements = value.toArray();
    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 (Object collElement : collElements) {
            if (!ec.getApiAdapter().isDetached(collElement) && !ec.getApiAdapter().isPersistent(collElement)) {
                // Element is not persistent so throw exception
                throw new ReachableObjectNotCascadedException(mmd.getFullFieldName(), collElement);
            }
        }
    } else {
        // Reachability
        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
            NucleusLogger.PERSISTENCE.debug(Localiser.msg("007007", mmd.getFullFieldName()));
        }
    }
    // Check if some elements need attaching
    // TODO Investigate if we can just use the attachCopy route below and skip off this check
    boolean needsAttaching = false;
    for (Object collElement : collElements) {
        if (ownerOP.getExecutionContext().getApiAdapter().isDetached(collElement)) {
            needsAttaching = true;
            break;
        }
    }
    if (needsAttaching) {
        // Create a wrapper and attach the elements (and add the others)
        SCO collWrapper = replaceFieldWithWrapper(ownerOP, null);
        if (value.size() > 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 (value.size() > 0) {
            // Add the elements direct to the datastore
            ((CollectionStore) storeMgr.getBackingStoreForField(ownerOP.getExecutionContext().getClassLoaderResolver(), mmd, value.getClass())).addAll(ownerOP, value, 0);
            // Create a SCO wrapper with the elements loaded
            replaceFieldWithWrapper(ownerOP, value);
        } else {
            if (mmd.getRelationType(ownerOP.getExecutionContext().getClassLoaderResolver()) == RelationType.MANY_TO_MANY_BI) {
                // Create a SCO wrapper, pass in null so it loads any from the datastore (on other side?)
                replaceFieldWithWrapper(ownerOP, null);
            } else {
                // Create a SCO wrapper, pass in empty collection to avoid loading from DB (extra SQL)
                replaceFieldWithWrapper(ownerOP, value);
            }
        }
    }
}
Also used : ExecutionContext(org.datanucleus.ExecutionContext) Collection(java.util.Collection) ObjectProvider(org.datanucleus.state.ObjectProvider) CollectionStore(org.datanucleus.store.types.scostore.CollectionStore) SCO(org.datanucleus.store.types.SCO) BackedSCO(org.datanucleus.store.types.wrappers.backed.BackedSCO) ReachableObjectNotCascadedException(org.datanucleus.exceptions.ReachableObjectNotCascadedException)

Example 95 with ObjectProvider

use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.

the class EmbeddedMapping method getObject.

/**
 * Accessor for the embedded object from the result set
 * @param ec ExecutionContext
 * @param rs The ResultSet
 * @param param Array of param numbers in the ResultSet for the fields of this object
 * @param ownerOP ObjectProvider of the owning object containing this embedded object
 * @param ownerFieldNumber Field number in the owning object where this is stored
 * @return The embedded object
 */
public Object getObject(ExecutionContext ec, ResultSet rs, int[] param, ObjectProvider ownerOP, int ownerFieldNumber) {
    Object value = null;
    int n = 0;
    // Determine the type of the embedded object
    AbstractClassMetaData embCmd = this.embCmd;
    if (discrimMapping != null) {
        Object discrimValue = discrimMapping.getObject(ec, rs, new int[] { param[n] });
        String className = ec.getMetaDataManager().getClassNameFromDiscriminatorValue((String) discrimValue, discrimMetaData);
        embCmd = storeMgr.getMetaDataManager().getMetaDataForClass(className, clr);
        n++;
    }
    // Create a persistable to put the values into
    Class embeddedType = clr.classForName(embCmd.getFullClassName());
    if (mmd.getFieldTypes() != null && mmd.getFieldTypes().length > 0) {
        // Embedded type has field-type defined so use that as our embedded type
        embeddedType = ec.getClassLoaderResolver().classForName(mmd.getFieldTypes()[0]);
    }
    ObjectProvider embOP = ec.getNucleusContext().getObjectProviderFactory().newForHollow(ec, embeddedType, null);
    embOP.setPcObjectType(objectType);
    value = embOP.getObject();
    String nullColumn = null;
    String nullValue = null;
    if (emd != null) {
        nullColumn = emd.getNullIndicatorColumn();
        nullValue = emd.getNullIndicatorValue();
    }
    // Populate the field values
    for (int i = 0; i < javaTypeMappings.size(); i++) {
        JavaTypeMapping mapping = javaTypeMappings.get(i);
        int embAbsFieldNum = embCmd.getAbsolutePositionOfMember(mapping.getMemberMetaData().getName());
        if (embAbsFieldNum >= 0) {
            // Mapping for field that is present in this embedded type, so set the field
            if (mapping instanceof EmbeddedPCMapping) {
                // We have a nested embedded
                int numSubParams = mapping.getNumberOfDatastoreMappings();
                int[] subParam = new int[numSubParams];
                int k = 0;
                for (int j = n; j < n + numSubParams; j++) {
                    subParam[k++] = param[j];
                }
                n += numSubParams;
                // Use the sub-object mapping to extract the value for that object
                Object subValue = mapping.getObject(ec, rs, subParam, embOP, embAbsFieldNum);
                if (subValue != null) {
                    embOP.replaceField(embAbsFieldNum, subValue);
                }
            // TODO Check the null column and its value in the sub-embedded ?
            } else {
                if (mapping.getNumberOfDatastoreMappings() > 0) {
                    // Extract the value(s) for this field and update the PC if it is not null
                    int[] posMapping = new int[mapping.getNumberOfDatastoreMappings()];
                    for (int j = 0; j < posMapping.length; j++) {
                        posMapping[j] = param[n++];
                    }
                    Object fieldValue = mapping.getObject(ec, rs, posMapping);
                    // Check for the null column and its value and break if this matches the null check
                    if (nullColumn != null && mapping.getMemberMetaData().getColumnMetaData()[0].getName().equals(nullColumn)) {
                        if ((nullValue == null && fieldValue == null) || (nullValue != null && fieldValue != null && fieldValue.toString().equals(nullValue))) {
                            value = null;
                            break;
                        }
                    }
                    // Set the field value
                    if (fieldValue != null) {
                        embOP.replaceField(embAbsFieldNum, fieldValue);
                    } else {
                        // If the value is null, but the field is not a primitive update it
                        AbstractMemberMetaData embFmd = embCmd.getMetaDataForManagedMemberAtAbsolutePosition(embAbsFieldNum);
                        if (!embFmd.getType().isPrimitive()) {
                            embOP.replaceField(embAbsFieldNum, fieldValue);
                        }
                    }
                }
            }
        } else {
            // Mapping not present in this embedded type so maybe subclass, so just omit the positions
            int numSubParams = mapping.getNumberOfDatastoreMappings();
            n += numSubParams;
        }
    }
    // Update owner field in the element (if present)
    if (emd != null) {
        String ownerField = emd.getOwnerMember();
        if (ownerField != null) {
            int ownerFieldNumberInElement = embCmd.getAbsolutePositionOfMember(ownerField);
            if (ownerFieldNumberInElement >= 0) {
                embOP.replaceField(ownerFieldNumberInElement, ownerOP != null ? ownerOP.getObject() : null);
            }
        }
    }
    // Register the owner-embedded ObjectProvider relation now we have values set
    if (value != null && ownerOP != null) {
        ec.registerEmbeddedRelation(ownerOP, ownerFieldNumber, embOP);
    }
    return value;
}
Also used : ObjectProvider(org.datanucleus.state.ObjectProvider) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Aggregations

ObjectProvider (org.datanucleus.state.ObjectProvider)160 ExecutionContext (org.datanucleus.ExecutionContext)85 Iterator (java.util.Iterator)43 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)34 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)25 Map (java.util.Map)22 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)22 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)21 SQLException (java.sql.SQLException)17 Collection (java.util.Collection)16 ApiAdapter (org.datanucleus.api.ApiAdapter)16 NucleusObjectNotFoundException (org.datanucleus.exceptions.NucleusObjectNotFoundException)16 SCOCollectionIterator (org.datanucleus.store.types.SCOCollectionIterator)16 ArrayList (java.util.ArrayList)14 HashSet (java.util.HashSet)14 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)14 NucleusException (org.datanucleus.exceptions.NucleusException)13 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)13 ListIterator (java.util.ListIterator)12 SQLController (org.datanucleus.store.rdbms.SQLController)12