use of org.eclipse.persistence.annotations.CacheKeyType 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.annotations.CacheKeyType 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.annotations.CacheKeyType in project eclipselink by eclipse-ee4j.
the class MappedKeyMapContainerPolicy method valueFromPKList.
/**
* INTERNAL:
* This method is used to load a relationship from a list of PKs. This list
* may be available if the relationship has been cached.
*/
@Override
public Object valueFromPKList(Object[] pks, AbstractRecord foreignKeys, ForeignReferenceMapping mapping, AbstractSession session) {
int mapSize = pks.length / 2;
Object result = containerInstance(mapSize);
Object[] keys = new Object[mapSize];
Object[] values = new Object[mapSize];
for (int index = 0; index < pks.length; ++index) {
keys[index / 2] = pks[index];
++index;
values[index / 2] = pks[index];
}
List<Object> keyObjects = keyMapping.createMapComponentsFromSerializableKeyInfo(keys, session);
if (((DatabaseMapping) valueMapping).isElementCollectionMapping()) {
for (int i = 0; i < mapSize; i++) {
addInto(keyObjects.get(i), values[i], result, session);
}
} else {
Map<Object, Object> fromCache = session.getIdentityMapAccessorInstance().getAllFromIdentityMapWithEntityPK(values, elementDescriptor);
List foreignKeyValues = new ArrayList(pks.length - fromCache.size());
CacheKeyType cacheKeyType = this.elementDescriptor.getCachePolicy().getCacheKeyType();
for (int index = 0; index < mapSize; ++index) {
Object pk = values[index];
if (!fromCache.containsKey(pk)) {
if (cacheKeyType == CacheKeyType.CACHE_ID) {
foreignKeyValues.add(Arrays.asList(((CacheId) pk).getPrimaryKey()));
} else {
foreignKeyValues.add(pk);
}
}
}
if (!foreignKeyValues.isEmpty()) {
if (foreignKeyValues.size() == pks.length) {
// need to find all of the entities so just perform a FK search
return session.executeQuery(mapping.getSelectionQuery(), foreignKeys);
}
ReadAllQuery query = new ReadAllQuery(elementDescriptor.getJavaClass());
query.setIsExecutionClone(true);
query.addArgument(ForeignReferenceMapping.QUERY_BATCH_PARAMETER);
query.setSession(session);
query.setSelectionCriteria(elementDescriptor.buildBatchCriteriaByPK(query.getExpressionBuilder(), query));
int pkCount = foreignKeyValues.size();
Collection<Object> temp = new ArrayList<>();
List arguments = new ArrayList();
arguments.add(foreignKeyValues);
if (pkCount > 1000) {
int index = 0;
while (index + 1000 < pkCount) {
// some databases only support ins < 1000 entries
List pkList = new ArrayList();
pkList.addAll(foreignKeyValues.subList(index, index + 1000));
arguments.set(0, pkList);
query.setArgumentValues(arguments);
temp.addAll((Collection<Object>) session.executeQuery(query));
index += 1000;
}
foreignKeyValues = foreignKeyValues.subList(index, pkCount);
}
arguments.set(0, foreignKeyValues);
query.setArgumentValues(arguments);
// need to put the translation row here or it will be replaced later.
temp.addAll((Collection<Object>) session.executeQuery(query));
if (temp.size() < pkCount) {
// element. Execute a reload based on FK.
return session.executeQuery(mapping.getSelectionQuery(), foreignKeys);
}
for (Object element : temp) {
Object pk = elementDescriptor.getObjectBuilder().extractPrimaryKeyFromObject(element, session);
fromCache.put(pk, element);
}
}
Iterator<Object> keyIterator = keyObjects.iterator();
for (Object key : values) {
addInto(keyIterator.next(), fromCache.get(key), result, session);
}
}
return result;
}
use of org.eclipse.persistence.annotations.CacheKeyType in project eclipselink by eclipse-ee4j.
the class OneToOneMapping method createMapComponentsFromSerializableKeyInfo.
/**
* INTERNAL:
* Create an instance of the Key object from the key information extracted from the map.
* This may return the value directly in case of a simple key or will be used as the FK to load a related entity.
*/
@Override
public List<Object> createMapComponentsFromSerializableKeyInfo(Object[] keyInfo, AbstractSession session) {
List<Object> orderedResult = new ArrayList<>(keyInfo.length);
Map<Object, Object> fromCache = session.getIdentityMapAccessorInstance().getAllFromIdentityMapWithEntityPK(keyInfo, referenceDescriptor);
List foreignKeyValues = new ArrayList(keyInfo.length - fromCache.size());
CacheKeyType cacheKeyType = referenceDescriptor.getCachePolicy().getCacheKeyType();
for (int index = 0; index < keyInfo.length; ++index) {
Object pk = keyInfo[index];
if (!fromCache.containsKey(pk)) {
if (cacheKeyType == CacheKeyType.CACHE_ID) {
foreignKeyValues.add(Arrays.asList(((CacheId) pk).getPrimaryKey()));
} else {
foreignKeyValues.add(pk);
}
}
}
if (!foreignKeyValues.isEmpty()) {
ReadAllQuery query = new ReadAllQuery(referenceDescriptor.getJavaClass());
query.setIsExecutionClone(true);
query.addArgument(ForeignReferenceMapping.QUERY_BATCH_PARAMETER);
query.addArgumentValue(foreignKeyValues);
query.setSession(session);
query.setSelectionCriteria(referenceDescriptor.buildBatchCriteriaByPK(query.getExpressionBuilder(), query));
Collection<Object> temp = (Collection<Object>) session.executeQuery(query);
for (Object element : temp) {
Object pk = referenceDescriptor.getObjectBuilder().extractPrimaryKeyFromObject(element, session);
fromCache.put(pk, element);
}
}
for (Object key : keyInfo) {
orderedResult.add(fromCache.get(key));
}
return orderedResult;
}
Aggregations