use of org.eclipse.persistence.internal.queries.JoinedAttributeManager in project eclipselink by eclipse-ee4j.
the class ReportQueryResult method processItem.
/**
* INTERNAL:
* Return a value from an item and database row (converted from raw field values using the mapping).
*/
protected Object processItem(ReportQuery query, AbstractRecord row, Vector toManyData, ReportItem item) {
JoinedAttributeManager joinManager = null;
if (item.hasJoining()) {
joinManager = item.getJoinedAttributeManager();
if (joinManager.isToManyJoin()) {
// PERF: Only reset data-result if unset, must only occur once per item, not per row (n vs n^2).
if (joinManager.getDataResults_() == null) {
joinManager.setDataResults(new ArrayList(toManyData), query.getSession());
}
}
}
Object value = null;
int rowSize = row.size();
int itemIndex = item.getResultIndex();
DatabaseMapping mapping = item.getMapping();
ClassDescriptor descriptor = item.getDescriptor();
if (item.getAttributeExpression() != null) {
if (descriptor == null && mapping != null) {
descriptor = mapping.getReferenceDescriptor();
}
if (mapping != null && (mapping.isAbstractColumnMapping() || mapping.isDirectCollectionMapping())) {
if (itemIndex >= rowSize) {
throw QueryException.reportQueryResultSizeMismatch(itemIndex + 1, rowSize);
}
value = processItemFromMapping(query, row, mapping, item, itemIndex);
// GF_ISSUE_395+
if (this.key != null) {
this.key.append(value);
this.key.append("_");
}
} else if (descriptor != null) {
// Item is for an object result.
int size = descriptor.getAllSelectionFields(query).size();
if (itemIndex + size > rowSize) {
throw QueryException.reportQueryResultSizeMismatch(itemIndex + size, rowSize);
}
AbstractRecord subRow = row;
// Check if at the start of the row, then avoid building a subRow.
if (itemIndex > 0) {
Vector<DatabaseField> trimedFields = new NonSynchronizedSubVector<>(row.getFields(), itemIndex, rowSize);
Vector trimedValues = new NonSynchronizedSubVector(row.getValues(), itemIndex, rowSize);
subRow = new DatabaseRecord(trimedFields, trimedValues);
}
if (mapping != null && mapping.isAggregateObjectMapping()) {
value = ((AggregateObjectMapping) mapping).buildAggregateFromRow(subRow, null, null, joinManager, query, false, query.getSession(), true);
} else {
// TODO : Support prefrechedCacheKeys in report query
value = descriptor.getObjectBuilder().buildObject(query, subRow, joinManager);
}
// a specific mapping. This could happen in a MapContainerPolicy
if (item.getAttributeExpression().isMapEntryExpression() && mapping.isCollectionMapping()) {
Object rowKey = null;
if (mapping.getContainerPolicy().isMapPolicy() && !mapping.getContainerPolicy().isMappedKeyMapPolicy()) {
rowKey = mapping.getContainerPolicy().keyFrom(value, query.getSession());
} else {
rowKey = mapping.getContainerPolicy().buildKey(subRow, query, null, query.getSession(), true);
}
if (((MapEntryExpression) item.getAttributeExpression()).shouldReturnMapEntry()) {
value = new Association(rowKey, value);
} else {
value = rowKey;
}
}
// GF_ISSUE_395
if (this.key != null) {
Object primaryKey = descriptor.getObjectBuilder().extractPrimaryKeyFromRow(subRow, query.getSession());
if (primaryKey != null) {
// GF3233 NPE is caused by processing the null PK being extracted from referenced target with null values in database.
this.key.append(primaryKey);
}
this.key.append("_");
}
} else {
value = row.getValues().get(itemIndex);
// GF_ISSUE_395
if (this.key != null) {
this.key.append(value);
}
}
}
return value;
}
use of org.eclipse.persistence.internal.queries.JoinedAttributeManager in project eclipselink by eclipse-ee4j.
the class ObjectBuilder method buildObjectsFromCursorInto.
/**
* Return a container which contains the instances of the receivers javaClass.
* Set the fields of the instance to the values stored in the database rows.
*/
public Object buildObjectsFromCursorInto(ReadAllQuery query, List databaseRows, Object domainObjects) {
AbstractSession session = query.getSession();
session.startOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
try {
InheritancePolicy inheritancePolicy = null;
if (this.descriptor.hasInheritance()) {
inheritancePolicy = this.descriptor.getInheritancePolicy();
}
boolean isUnitOfWork = session.isUnitOfWork();
boolean shouldCacheQueryResults = query.shouldCacheQueryResults();
boolean shouldUseWrapperPolicy = query.shouldUseWrapperPolicy();
// PERF: Avoid lazy init of join manager if no joining.
JoinedAttributeManager joinManager = null;
if (query.hasJoining()) {
joinManager = query.getJoinedAttributeManager();
}
ContainerPolicy policy = query.getContainerPolicy();
if (policy.shouldAddAll()) {
List domainObjectsIn = new ArrayList();
List<AbstractRecord> databaseRowsIn = new ArrayList();
for (Enumeration iterator = ((Vector) databaseRows).elements(); iterator.hasMoreElements(); ) {
AbstractRecord databaseRow = (AbstractRecord) iterator.nextElement();
// PERF: 1-m joining nulls out duplicate rows.
if (databaseRow != null) {
domainObjectsIn.add(buildObject(query, databaseRow, joinManager, session, this.descriptor, inheritancePolicy, isUnitOfWork, shouldCacheQueryResults, shouldUseWrapperPolicy));
databaseRowsIn.add(databaseRow);
}
}
policy.addAll(domainObjectsIn, domainObjects, session, databaseRowsIn, query, null, true);
} else {
boolean quickAdd = (domainObjects instanceof Collection) && !this.hasWrapperPolicy;
for (Enumeration iterator = ((Vector) databaseRows).elements(); iterator.hasMoreElements(); ) {
AbstractRecord databaseRow = (AbstractRecord) iterator.nextElement();
// PERF: 1-m joining nulls out duplicate rows.
if (databaseRow != null) {
Object domainObject = buildObject(query, databaseRow, joinManager, session, this.descriptor, inheritancePolicy, isUnitOfWork, shouldCacheQueryResults, shouldUseWrapperPolicy);
if (quickAdd) {
((Collection) domainObjects).add(domainObject);
} else {
policy.addInto(domainObject, domainObjects, session, databaseRow, query, null, true);
}
}
}
}
} finally {
session.endOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
}
return domainObjects;
}
use of org.eclipse.persistence.internal.queries.JoinedAttributeManager in project eclipselink by eclipse-ee4j.
the class ScrollableCursor method retrievePreviousObject.
/**
* INTERNAL:
* CR#4139
* Read the previous row from the result set. It is used solely
* for scrollable cursor support.
*/
protected Object retrievePreviousObject() throws DatabaseException {
while (true) {
int currentPosition = getPosition();
if (currentPosition <= (this.objectCollection.size() + 1)) {
// If at first of cursor, move cursor to beforeFirst.
if ((currentPosition == (this.objectCollection.size() + 1)) && (!isClosed())) {
getAccessor().cursorRetrievePreviousRow(this.fields, this.resultSet, this.executionSession);
}
if (currentPosition <= 1) {
// Cursor can not move back further than beforeFirst.
this.position = 0;
return null;
} else {
this.position = currentPosition - 1;
return this.objectCollection.get(this.position - 1);
}
}
if (isClosed()) {
return null;
}
AbstractRecord row = null;
if (this.previousRow == null) {
row = getAccessor().cursorRetrievePreviousRow(this.fields, this.resultSet, this.executionSession);
} else {
row = this.previousRow;
this.previousRow = null;
}
this.position = currentPosition - 1;
if (row == null) {
return null;
}
// If using 1-m joining need to fetch 1-m rows as well.
if (this.query.isObjectLevelReadQuery() && ((ObjectLevelReadQuery) this.query).hasJoining()) {
JoinedAttributeManager joinManager = ((ObjectLevelReadQuery) this.query).getJoinedAttributeManager();
if (joinManager.isToManyJoin()) {
this.previousRow = joinManager.processDataResults(row, this, false);
}
}
Object object = buildAndRegisterObject(row);
// keep going until find one that conforms.
if (object == InvalidObject.instance) {
continue;
}
return object;
}
}
use of org.eclipse.persistence.internal.queries.JoinedAttributeManager in project eclipselink by eclipse-ee4j.
the class ScrollableCursor method retrieveNextObject.
/**
* INTERNAL:
* Read the next row from the result set.
*/
@Override
protected Object retrieveNextObject() throws DatabaseException {
while (true) {
int currentPosition = getPosition();
if (currentPosition < this.objectCollection.size()) {
this.position = currentPosition + 1;
return this.objectCollection.get(currentPosition);
}
if (isClosed()) {
return null;
}
AbstractRecord row = null;
// if the end of the cursor has been reached, do not retrieve more rows
if (!this.atEndOfCursor) {
if (this.nextRow == null) {
row = getAccessor().cursorRetrieveNextRow(this.fields, this.resultSet, this.executionSession);
} else {
row = this.nextRow;
this.nextRow = null;
}
}
// bug 309142
this.position = currentPosition + 1;
if (row == null) {
this.atEndOfCursor = true;
return null;
}
// If using 1-m joining need to fetch 1-m rows as well.
if (this.query.isObjectLevelReadQuery() && ((ObjectLevelReadQuery) this.query).hasJoining()) {
JoinedAttributeManager joinManager = ((ObjectLevelReadQuery) this.query).getJoinedAttributeManager();
if (joinManager.isToManyJoin()) {
this.nextRow = joinManager.processDataResults(row, this, true);
// if the join manager returns a null next row, we are at the end of the cursor
if (this.nextRow == null) {
this.atEndOfCursor = true;
}
}
}
Object object = buildAndRegisterObject(row);
if (object == InvalidObject.instance) {
continue;
}
return object;
}
}
use of org.eclipse.persistence.internal.queries.JoinedAttributeManager in project eclipselink by eclipse-ee4j.
the class ObjectBuilder method buildObjectsInto.
/**
* Return a container which contains the instances of the receivers javaClass.
* Set the fields of the instance to the values stored in the database rows.
*/
public Object buildObjectsInto(ReadAllQuery query, List databaseRows, Object domainObjects) {
if (databaseRows instanceof ThreadCursoredList) {
return buildObjectsFromCursorInto(query, databaseRows, domainObjects);
}
int size = databaseRows.size();
if (size > 0) {
AbstractSession session = query.getSession();
session.startOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
try {
InheritancePolicy inheritancePolicy = null;
if (this.descriptor.hasInheritance()) {
inheritancePolicy = this.descriptor.getInheritancePolicy();
}
boolean isUnitOfWork = session.isUnitOfWork();
boolean shouldCacheQueryResults = query.shouldCacheQueryResults();
boolean shouldUseWrapperPolicy = query.shouldUseWrapperPolicy();
// PERF: Avoid lazy init of join manager if no joining.
JoinedAttributeManager joinManager = null;
if (query.hasJoining()) {
joinManager = query.getJoinedAttributeManager();
}
if (this.descriptor.getCachePolicy().shouldPrefetchCacheKeys() && query.shouldMaintainCache() && !query.shouldRetrieveBypassCache()) {
Object[] pkList = new Object[size];
for (int i = 0; i < size; ++i) {
pkList[i] = extractPrimaryKeyFromRow((AbstractRecord) databaseRows.get(i), session);
}
query.setPrefetchedCacheKeys(session.getIdentityMapAccessorInstance().getAllCacheKeysFromIdentityMapWithEntityPK(pkList, descriptor));
}
ContainerPolicy policy = query.getContainerPolicy();
if (policy.shouldAddAll()) {
List domainObjectsIn = new ArrayList(size);
List<AbstractRecord> databaseRowsIn = new ArrayList(size);
for (int index = 0; index < size; index++) {
AbstractRecord databaseRow = (AbstractRecord) databaseRows.get(index);
// PERF: 1-m joining nulls out duplicate rows.
if (databaseRow != null) {
domainObjectsIn.add(buildObject(query, databaseRow, joinManager, session, this.descriptor, inheritancePolicy, isUnitOfWork, shouldCacheQueryResults, shouldUseWrapperPolicy));
databaseRowsIn.add(databaseRow);
}
}
policy.addAll(domainObjectsIn, domainObjects, session, databaseRowsIn, query, null, true);
} else {
boolean quickAdd = (domainObjects instanceof Collection) && !this.hasWrapperPolicy;
for (int index = 0; index < size; index++) {
AbstractRecord databaseRow = (AbstractRecord) databaseRows.get(index);
// PERF: 1-m joining nulls out duplicate rows.
if (databaseRow != null) {
Object domainObject = buildObject(query, databaseRow, joinManager, session, this.descriptor, inheritancePolicy, isUnitOfWork, shouldCacheQueryResults, shouldUseWrapperPolicy);
if (quickAdd) {
((Collection) domainObjects).add(domainObject);
} else {
policy.addInto(domainObject, domainObjects, session, databaseRow, query, null, true);
}
}
}
}
} finally {
session.endOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
}
}
return domainObjects;
}
Aggregations