Search in sources :

Example 1 with CacheId

use of org.eclipse.persistence.internal.identitymaps.CacheId in project eclipselink by eclipse-ee4j.

the class CMP3Policy method createPrimaryKeyFromId.

/**
 * INTERNAL:
 * Use the key to create a EclipseLink primary key.
 * If the key is simple (direct mapped) then just add it to a vector,
 * otherwise must go through the inefficient process of copying the key into the bean
 * and extracting the key from the bean.
 */
@Override
public Object createPrimaryKeyFromId(Object key, AbstractSession session) {
    // If the descriptor primary key is mapped through direct-to-field mappings,
    // then no elaborate conversion is required.
    // If key is compound, add each value to the vector.
    KeyElementAccessor[] pkElementArray = this.getKeyClassFields();
    Object[] primaryKey = null;
    if (getDescriptor().getCacheKeyType() != CacheKeyType.ID_VALUE) {
        primaryKey = new Object[pkElementArray.length];
    }
    for (int index = 0; index < pkElementArray.length; index++) {
        DatabaseMapping mapping = pkElementArray[index].getMapping();
        Object fieldValue = null;
        if (mapping.isAbstractColumnMapping()) {
            if (pkElementArray[index].isNestedAccessor()) {
                // We have nested aggregate(s) in the embedded id pkclass.
                DatabaseField keyField = pkElementArray[index].getDatabaseField();
                Object keyToUse = key;
                DatabaseMapping keyMapping = getDescriptor().getObjectBuilder().getMappingForField(keyField);
                if (keyMapping.isAggregateMapping()) {
                    keyMapping = keyMapping.getReferenceDescriptor().getObjectBuilder().getMappingForField(keyField);
                    // Keep driving down the nested aggregates ...
                    while (keyMapping.isAggregateMapping()) {
                        keyToUse = keyMapping.getRealAttributeValueFromObject(keyToUse, session);
                        keyMapping = keyMapping.getReferenceDescriptor().getObjectBuilder().getMappingForField(keyField);
                    }
                    fieldValue = ((AbstractColumnMapping) mapping).getFieldValue(pkElementArray[index].getValue(keyToUse, session), session);
                } else {
                    // This should never hit but just in case ... better to get a proper exception rather than a NPE etc.
                    fieldValue = ((AbstractColumnMapping) mapping).getFieldValue(pkElementArray[index].getValue(keyToUse, session), session);
                }
            } else {
                fieldValue = ((AbstractColumnMapping) mapping).getFieldValue(pkElementArray[index].getValue(key, session), session);
            }
        } else {
            fieldValue = pkElementArray[index].getValue(key, session);
            if ((fieldValue != null) && (pkClass != null) && (mapping.isOneToOneMapping())) {
                OneToOneMapping refmapping = (OneToOneMapping) mapping;
                DatabaseField targetKey = refmapping.getSourceToTargetKeyFields().get(pkElementArray[index].getDatabaseField());
                CMPPolicy refPolicy = refmapping.getReferenceDescriptor().getCMPPolicy();
                if (refPolicy.isCMP3Policy()) {
                    Class<Object> aPKClass = refPolicy.getPKClass();
                    if ((aPKClass != null) && (aPKClass != fieldValue.getClass()) && (!aPKClass.isAssignableFrom(fieldValue.getClass()))) {
                        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("invalid_pk_class", new Object[] { aPKClass, fieldValue.getClass() }));
                    }
                    fieldValue = ((CMP3Policy) refPolicy).getPkValueFromKeyForField(fieldValue, targetKey, session);
                }
            }
        }
        if (getDescriptor().getCacheKeyType() == CacheKeyType.ID_VALUE) {
            return fieldValue;
        }
        primaryKey[index] = fieldValue;
    }
    return new CacheId(primaryKey);
}
Also used : CMPPolicy(org.eclipse.persistence.descriptors.CMPPolicy) CacheId(org.eclipse.persistence.internal.identitymaps.CacheId) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) OneToOneMapping(org.eclipse.persistence.mappings.OneToOneMapping)

Example 2 with CacheId

use of org.eclipse.persistence.internal.identitymaps.CacheId in project eclipselink by eclipse-ee4j.

the class EISOneToOneMapping method extractPrimaryKeysForReferenceObjectFromRow.

/**
 * INTERNAL:
 * Return the primary key for the reference object (i.e. the object
 * object referenced by domainObject and specified by mapping).
 * This key will be used by a RemoteValueHolder.
 */
@Override
public Object extractPrimaryKeysForReferenceObjectFromRow(AbstractRecord row) {
    List<DatabaseField> primaryKeyFields = getReferenceDescriptor().getPrimaryKeyFields();
    Object[] result = new Object[primaryKeyFields.size()];
    for (int index = 0; index < primaryKeyFields.size(); index++) {
        DatabaseField targetKeyField = primaryKeyFields.get(index);
        DatabaseField sourceKeyField = getTargetToSourceKeyFields().get(targetKeyField);
        if (sourceKeyField == null) {
            return null;
        }
        result[index] = row.get(sourceKeyField);
        if (getReferenceDescriptor().getCachePolicy().getCacheKeyType() == CacheKeyType.ID_VALUE) {
            return result[index];
        }
    }
    return new CacheId(result);
}
Also used : CacheId(org.eclipse.persistence.internal.identitymaps.CacheId) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField)

Example 3 with CacheId

use of org.eclipse.persistence.internal.identitymaps.CacheId in project eclipselink by eclipse-ee4j.

the class ObjectBuilder method extractPrimaryKeyFromRow.

/**
 * Extract primary key values from the specified row.
 * null is returned if the row does not contain the key.
 */
public Object extractPrimaryKeyFromRow(AbstractRecord databaseRow, AbstractSession session) {
    if (databaseRow.hasSopObject()) {
        // Entity referencing ForeignReferenceMapping has set attribute extracted from sopObject as a sopObject into a new empty row.
        return extractPrimaryKeyFromObject(databaseRow.getSopObject(), session);
    }
    List<DatabaseField> primaryKeyFields = this.descriptor.getPrimaryKeyFields();
    if (null == primaryKeyFields) {
        return null;
    }
    List<Class<?>> primaryKeyClassifications = getPrimaryKeyClassifications();
    int size = primaryKeyFields.size();
    Object[] primaryKeyValues = null;
    CacheKeyType cacheKeyType = this.descriptor.getCachePolicy().getCacheKeyType();
    if (cacheKeyType != CacheKeyType.ID_VALUE) {
        primaryKeyValues = new Object[size];
    }
    int numberOfNulls = 0;
    // PERF: use index not enumeration
    for (int index = 0; index < size; index++) {
        DatabaseField field = primaryKeyFields.get(index);
        // Ensure that the type extracted from the row is the same type as in the object.
        Class<?> classification = primaryKeyClassifications.get(index);
        Object value = databaseRow.get(field);
        if (value != null) {
            if (value.getClass() != classification) {
                value = session.getPlatform(this.descriptor.getJavaClass()).convertObject(value, classification);
            }
            if (cacheKeyType == CacheKeyType.ID_VALUE) {
                return value;
            }
            primaryKeyValues[index] = value;
        } else {
            if (this.mayHaveNullInPrimaryKey) {
                numberOfNulls++;
                if (numberOfNulls < size) {
                    primaryKeyValues[index] = null;
                } else {
                    // Must have some non null elements. If all elements are null return null.
                    return null;
                }
            } else {
                return null;
            }
        }
    }
    return new CacheId(primaryKeyValues);
}
Also used : CacheId(org.eclipse.persistence.internal.identitymaps.CacheId) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) CacheKeyType(org.eclipse.persistence.annotations.CacheKeyType) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject)

Example 4 with CacheId

use of org.eclipse.persistence.internal.identitymaps.CacheId in project eclipselink by eclipse-ee4j.

the class ObjectBuilder method extractPrimaryKeyFromObject.

/**
 * Extract primary key attribute values from the domainObject.
 */
public Object extractPrimaryKeyFromObject(Object domainObject, AbstractSession session, boolean shouldReturnNullIfNull) {
    if (domainObject == null) {
        return null;
    }
    // Avoid using the cached id for XML, as the relational descriptor may be different than the xml one.
    boolean isPersistenceEntity = (domainObject instanceof PersistenceEntity) && (!isXMLObjectBuilder());
    if (isPersistenceEntity) {
        Object primaryKey = ((PersistenceEntity) domainObject)._persistence_getId();
        if (primaryKey != null) {
            return primaryKey;
        }
    }
    ClassDescriptor descriptor = this.descriptor;
    boolean isNull = false;
    // Allow for inheritance, the concrete descriptor must always be used.
    if (descriptor.hasInheritance() && (domainObject.getClass() != descriptor.getJavaClass()) && (!domainObject.getClass().getSuperclass().equals(descriptor.getJavaClass()))) {
        return session.getDescriptor(domainObject).getObjectBuilder().extractPrimaryKeyFromObject(domainObject, session, shouldReturnNullIfNull);
    }
    CacheKeyType cacheKeyType = descriptor.getCachePolicy().getCacheKeyType();
    List<DatabaseField> primaryKeyFields = descriptor.getPrimaryKeyFields();
    Object[] primaryKeyValues = null;
    if (cacheKeyType != CacheKeyType.ID_VALUE) {
        primaryKeyValues = new Object[primaryKeyFields.size()];
    }
    List<DatabaseMapping> mappings = getPrimaryKeyMappings();
    int size = mappings.size();
    // PERF: optimize simple case of direct mapped singleton primary key.
    if (descriptor.hasSimplePrimaryKey()) {
        // PERF: use index not enumeration.
        for (int index = 0; index < size; index++) {
            AbstractColumnMapping mapping = (AbstractColumnMapping) mappings.get(index);
            Object keyValue = mapping.valueFromObject(domainObject, primaryKeyFields.get(index), session);
            if (isPrimaryKeyComponentInvalid(keyValue, index)) {
                if (shouldReturnNullIfNull) {
                    return null;
                }
                isNull = true;
            }
            if (cacheKeyType == CacheKeyType.ID_VALUE) {
                if (isPersistenceEntity && (!isNull)) {
                    ((PersistenceEntity) domainObject)._persistence_setId(keyValue);
                }
                return keyValue;
            } else {
                primaryKeyValues[index] = keyValue;
            }
        }
    } else {
        AbstractRecord databaseRow = createRecordForPKExtraction(size, session);
        Set<DatabaseMapping> writtenMappings = new HashSet<>(size);
        // PERF: use index not enumeration
        for (int index = 0; index < size; index++) {
            DatabaseMapping mapping = mappings.get(index);
            // Primary key mapping may be null for aggregate collection.
            if (mapping != null && !writtenMappings.contains(mapping)) {
                mapping.writeFromObjectIntoRow(domainObject, databaseRow, session, WriteType.UNDEFINED);
                writtenMappings.add(mapping);
            }
        }
        List<Class<?>> primaryKeyClassifications = getPrimaryKeyClassifications();
        Platform platform = session.getPlatform(domainObject.getClass());
        // PERF: use index not enumeration
        for (int index = 0; index < size; index++) {
            // Ensure that the type extracted from the object is the same type as in the descriptor,
            // the main reason for this is that 1-1 can optimize on vh by getting from the row as the row-type.
            Class<?> classification = primaryKeyClassifications.get(index);
            Object value = databaseRow.get(primaryKeyFields.get(index));
            if (isPrimaryKeyComponentInvalid(value, index)) {
                if (shouldReturnNullIfNull) {
                    return null;
                }
                isNull = true;
            }
            value = platform.convertObject(value, classification);
            if (cacheKeyType == CacheKeyType.ID_VALUE) {
                if (isPersistenceEntity && (!isNull)) {
                    ((PersistenceEntity) domainObject)._persistence_setId(value);
                }
                return value;
            } else {
                primaryKeyValues[index] = value;
            }
        }
    }
    CacheId id = new CacheId(primaryKeyValues);
    if (isPersistenceEntity && (!isNull)) {
        ((PersistenceEntity) domainObject)._persistence_setId(id);
    }
    return id;
}
Also used : ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) Platform(org.eclipse.persistence.internal.databaseaccess.Platform) DatasourcePlatform(org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform) DatabasePlatform(org.eclipse.persistence.internal.databaseaccess.DatabasePlatform) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) AbstractColumnMapping(org.eclipse.persistence.mappings.foundation.AbstractColumnMapping) CacheId(org.eclipse.persistence.internal.identitymaps.CacheId) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) CacheKeyType(org.eclipse.persistence.annotations.CacheKeyType) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) IdentityHashSet(org.eclipse.persistence.internal.helper.IdentityHashSet) HashSet(java.util.HashSet)

Example 5 with CacheId

use of org.eclipse.persistence.internal.identitymaps.CacheId in project eclipselink by eclipse-ee4j.

the class UnmarshalRecordImpl method endDocument.

@Override
public void endDocument() throws SAXException {
    if (unmarshaller.getIDResolver() != null && parentRecord == null) {
        unmarshaller.getIDResolver().endDocument();
    }
    if (null != selfRecords) {
        for (int x = 0, selfRecordsSize = selfRecords.size(); x < selfRecordsSize; x++) {
            UnmarshalRecord selfRecord = selfRecords.get(x);
            if (selfRecord != null) {
                selfRecord.endDocument();
            }
        }
    }
    if (null != xPathNode.getSelfChildren()) {
        int selfChildrenSize = xPathNode.getSelfChildren().size();
        for (int x = 0; x < selfChildrenSize; x++) {
            XPathNode selfNode = xPathNode.getSelfChildren().get(x);
            if (null != selfNode.getNodeValue()) {
                selfNode.getNodeValue().endSelfNodeValue(this, selfRecords.get(x), attributes);
            }
        }
    }
    CoreDescriptor xmlDescriptor = treeObjectBuilder.getDescriptor();
    try {
        // All populated containerValues need to be set on the object
        if (null != populatedContainerValues) {
            for (int populatedCVSize = populatedContainerValues.size(), i = populatedCVSize - 1; i >= 0; i--) {
                ContainerValue cv = (populatedContainerValues.get(i));
                cv.setContainerInstance(currentObject, getContainerInstance(cv, cv.isDefaultEmptyContainer()));
            }
        }
        // Additionally if any containerValues are defaultEmptyContainerValues they need to be set to a new empty container
        if (null != defaultEmptyContainerValues) {
            for (int defaultEmptyCVSize = defaultEmptyContainerValues.size(), i = defaultEmptyCVSize - 1; i >= 0; i--) {
                ContainerValue cv = (defaultEmptyContainerValues.get(i));
                cv.setContainerInstance(currentObject, getContainerInstance(cv, cv.isDefaultEmptyContainer()));
            }
        }
        // trigger the mapping.
        if (null != nullCapableValues) {
            for (int x = 0, nullValuesSize = nullCapableValues.size(); x < nullValuesSize; x++) {
                nullCapableValues.get(x).setNullValue(currentObject, session);
            }
        }
        // PROCESS TRANSFORMATION MAPPINGS
        List<TransformationMapping> transformationMappings = treeObjectBuilder.getTransformationMappings();
        if (null != transformationMappings) {
            for (int x = 0, transformationMappingsSize = transformationMappings.size(); x < transformationMappingsSize; x++) {
                TransformationMapping transformationMapping = transformationMappings.get(x);
                transformationMapping.readFromRowIntoObject((XMLRecord) transformationRecord, currentObject, session, true);
            }
        }
        Unmarshaller.Listener listener = unmarshaller.getUnmarshalListener();
        if (listener != null) {
            if (this.parentRecord != null) {
                listener.afterUnmarshal(currentObject, parentRecord.getCurrentObject());
            } else {
                listener.afterUnmarshal(currentObject, null);
            }
        }
        // HANDLE POST BUILD EVENTS
        if (xmlDescriptor.hasEventManager()) {
            CoreDescriptorEventManager eventManager = xmlDescriptor.getEventManager();
            if (null != eventManager && eventManager.hasAnyEventListeners()) {
                DescriptorEvent event = new DescriptorEvent(currentObject);
                event.setSession((AbstractSession) session);
                // this);
                event.setRecord(null);
                event.setEventCode(DescriptorEventManager.PostBuildEvent);
                eventManager.executeEvent(event);
            }
        }
    } catch (EclipseLinkException e) {
        if (null == xmlReader.getErrorHandler()) {
            throw e;
        } else {
            SAXParseException saxParseException = new SAXParseException(null, getDocumentLocator(), e);
            xmlReader.getErrorHandler().error(saxParseException);
        }
    }
    // if the object has any primary key fields set, add it to the cache
    if (null != referenceResolver) {
        if (null != xmlDescriptor) {
            List primaryKeyFields = xmlDescriptor.getPrimaryKeyFields();
            if (null != primaryKeyFields) {
                int primaryKeyFieldsSize = primaryKeyFields.size();
                if (primaryKeyFieldsSize > 0) {
                    CacheId pk = (CacheId) treeObjectBuilder.extractPrimaryKeyFromObject(currentObject, session);
                    for (int x = 0; x < primaryKeyFieldsSize; x++) {
                        Object value = pk.getPrimaryKey()[x];
                        if (null == value) {
                            Field pkField = (Field) xmlDescriptor.getPrimaryKeyFields().get(x);
                            pk.set(x, unmarshaller.getContext().getValueByXPath(currentObject, pkField.getXPath(), pkField.getNamespaceResolver(), Object.class));
                        }
                    }
                    referenceResolver.putValue(xmlDescriptor.getJavaClass(), pk, currentObject);
                    if (unmarshaller.getIDResolver() != null) {
                        try {
                            if (primaryKeyFieldsSize > 1) {
                                Map<String, Object> idWrapper = new HashMap<>();
                                for (int x = 0; x < primaryKeyFieldsSize; x++) {
                                    String idName = (String) xmlDescriptor.getPrimaryKeyFieldNames().get(x);
                                    Object idValue = pk.getPrimaryKey()[x];
                                    idWrapper.put(idName, idValue);
                                }
                                unmarshaller.getIDResolver().bind(idWrapper, currentObject);
                            } else {
                                unmarshaller.getIDResolver().bind(pk.getPrimaryKey()[0], currentObject);
                            }
                        } catch (SAXException e) {
                            throw XMLMarshalException.unmarshalException(e);
                        }
                    }
                }
            }
        }
    }
    if (null != parentRecord) {
        reset();
    }
    // Set XML Location if applicable
    if (xmlLocation != null && ((Descriptor) xmlDescriptor).getLocationAccessor() != null) {
        ((Descriptor) xmlDescriptor).getLocationAccessor().setAttributeValueInObject(getCurrentObject(), xmlLocation);
    }
}
Also used : CoreDescriptorEventManager(org.eclipse.persistence.core.descriptors.CoreDescriptorEventManager) TransformationMapping(org.eclipse.persistence.internal.oxm.mappings.TransformationMapping) HashMap(java.util.HashMap) CoreDescriptor(org.eclipse.persistence.core.descriptors.CoreDescriptor) DescriptorEvent(org.eclipse.persistence.descriptors.DescriptorEvent) XPathNode(org.eclipse.persistence.internal.oxm.XPathNode) ContainerValue(org.eclipse.persistence.internal.oxm.ContainerValue) SAXException(org.xml.sax.SAXException) Field(org.eclipse.persistence.internal.oxm.mappings.Field) CoreField(org.eclipse.persistence.internal.core.helper.CoreField) EclipseLinkException(org.eclipse.persistence.exceptions.EclipseLinkException) SAXParseException(org.xml.sax.SAXParseException) CacheId(org.eclipse.persistence.internal.identitymaps.CacheId) Descriptor(org.eclipse.persistence.internal.oxm.mappings.Descriptor) CoreDescriptor(org.eclipse.persistence.core.descriptors.CoreDescriptor) List(java.util.List) ArrayList(java.util.ArrayList) Unmarshaller(org.eclipse.persistence.internal.oxm.Unmarshaller)

Aggregations

CacheId (org.eclipse.persistence.internal.identitymaps.CacheId)38 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)19 ArrayList (java.util.ArrayList)12 List (java.util.List)10 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)8 ConversionException (org.eclipse.persistence.exceptions.ConversionException)8 ConversionManager (org.eclipse.persistence.internal.helper.ConversionManager)8 CacheKey (org.eclipse.persistence.internal.identitymaps.CacheKey)5 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)5 HashMap (java.util.HashMap)4 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)4 XMLField (org.eclipse.persistence.oxm.XMLField)4 Vector (java.util.Vector)3 CacheKeyType (org.eclipse.persistence.annotations.CacheKeyType)3 CoreDescriptor (org.eclipse.persistence.core.descriptors.CoreDescriptor)3 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)3 Descriptor (org.eclipse.persistence.internal.oxm.mappings.Descriptor)3 ReadAllQuery (org.eclipse.persistence.queries.ReadAllQuery)3 SAXException (org.xml.sax.SAXException)3 SAXParseException (org.xml.sax.SAXParseException)3