/** * INTERNAL: All objects queried via a UnitOfWork get registered here. If the query went to the * database. * * <p>Involves registering the query result individually and in totality, and hence refreshing / * conforming is done here. * * @param result may be collection (read all) or an object (read one), or even a cursor. If in * transaction the shared cache will be bypassed, meaning the result may not be originals from * the parent but raw database rows. * @param unitOfWork the unitOfWork the result is being registered in. * @param arguments the original arguments/parameters passed to the query execution. Used by * conforming * @param buildDirectlyFromRows If in transaction must construct a registered result from raw * database rows. * @return the final (conformed, refreshed, wrapped) UnitOfWork query result */ public Object registerResultInUnitOfWork( Object result, UnitOfWorkImpl unitOfWork, AbstractRecord arguments, boolean buildDirectlyFromRows) { // For bug 2612366: Conforming results in UOW extremely slow. // Replacing results with registered versions in the UOW is a part of // conforming and is now done while conforming to maximize performance. if (shouldConformResultsInUnitOfWork() || this.descriptor.shouldAlwaysConformResultsInUnitOfWork()) { return conformResult(result, unitOfWork, arguments, buildDirectlyFromRows); } // When building directly from rows, one of the performance benefits // is that we no longer have to wrap and then unwrap the originals. // result is just a vector, not a collection of wrapped originals. // Also for cursors the initial connection is automatically registered. if (buildDirectlyFromRows) { List<AbstractRecord> rows = (List<AbstractRecord>) result; ContainerPolicy cp = getContainerPolicy(); int size = rows.size(); Object clones = cp.containerInstance(size); for (int index = 0; index < size; index++) { AbstractRecord row = rows.get(index); // null is placed in the row collection for 1-m joining to filter duplicate rows. if (row != null) { Object clone = buildObject(row); cp.addInto(clone, clones, unitOfWork, row, this); } } return clones; } ContainerPolicy cp; Cursor cursor = null; // If the query is redirected then the collection returned might no longer // correspond to the original container policy. CR#2342-S.M. if (getRedirector() != null) { cp = ContainerPolicy.buildPolicyFor(result.getClass()); } else { cp = getContainerPolicy(); } // In the case of cursors just register the initially read collection. if (cp.isCursorPolicy()) { cursor = (Cursor) result; // In nested UnitOfWork session might have been session of the parent. cursor.setSession(unitOfWork); cp = ContainerPolicy.buildPolicyFor(ClassConstants.Vector_class); result = cursor.getObjectCollection(); } Object clones = cp.containerInstance(cp.sizeFor(result)); AbstractSession sessionToUse = unitOfWork.getParent(); for (Object iter = cp.iteratorFor(result); cp.hasNext(iter); ) { Object object = cp.next(iter, sessionToUse); Object clone = registerIndividualResult(object, unitOfWork, this.joinedAttributeManager); cp.addInto(clone, clones, unitOfWork); } if (cursor != null) { cursor.setObjectCollection((Vector) clones); return cursor; } else { return clones; } }