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