* Return the value of the reference attribute or a value holder.
* Check whether the mapping's attribute should be optimized through batch and joining.
*/
protected Object valueFromRowInternal(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery sourceQuery, AbstractSession executionSession) throws DatabaseException {
// PERF: Direct variable access.
ReadQuery targetQuery = this.selectionQuery;
// Copy nested fetch group from the source query
if (targetQuery.isObjectLevelReadQuery() && targetQuery.getDescriptor().hasFetchGroupManager()) {
FetchGroup sourceFG = sourceQuery.getExecutionFetchGroup();
if (sourceFG != null) {
FetchGroup targetFetchGroup = sourceFG.getGroup(getAttributeName());
if(targetFetchGroup != null) {
// perf: bug#4751950, first prepare the query before cloning.
if (targetQuery.shouldPrepare()) {
targetQuery.checkPrepare(executionSession, row);
}
targetQuery = (ObjectLevelReadQuery)targetQuery.clone();
targetQuery.setIsExecutionClone(true);
((ObjectLevelReadQuery)targetQuery).setFetchGroup(targetFetchGroup);
}
}
}
// CR #4365, 3610825 - moved up from the block below, needs to be set with
// indirection off. Clone the query and set its id.
if (!this.indirectionPolicy.usesIndirection()) {
if (targetQuery == this.selectionQuery) {
// perf: bug#4751950, first prepare the query before cloning.
if (targetQuery.shouldPrepare()) {
targetQuery.checkPrepare(executionSession, row);
}
targetQuery = (ObjectLevelReadQuery)targetQuery.clone();
targetQuery.setIsExecutionClone(true);
}
targetQuery.setQueryId(sourceQuery.getQueryId());
((ObjectLevelReadQuery)targetQuery).setRequiresDeferredLocks(sourceQuery.requiresDeferredLocks());
}
// If the source query is cascading then the target query must use the same settings.
if (targetQuery.isObjectLevelReadQuery()) {
if (sourceQuery.shouldCascadeAllParts() || (this.isPrivateOwned && sourceQuery.shouldCascadePrivateParts()) || (this.cascadeRefresh && sourceQuery.shouldCascadeByMapping())) {
// If the target query has already been cloned (we're refreshing) avoid
// re-cloning the query again.
if (targetQuery == this.selectionQuery) {
// perf: bug#4751950, first prepare the query before cloning.
if (targetQuery.shouldPrepare()) {
targetQuery.checkPrepare(executionSession, row);
}
targetQuery = (ObjectLevelReadQuery)targetQuery.clone();
targetQuery.setIsExecutionClone(true);
}
((ObjectLevelReadQuery)targetQuery).setShouldRefreshIdentityMapResult(sourceQuery.shouldRefreshIdentityMapResult());
targetQuery.setCascadePolicy(sourceQuery.getCascadePolicy());
// For queries that have turned caching off, such as aggregate collection, leave it off.
if (targetQuery.shouldMaintainCache()) {
targetQuery.setShouldMaintainCache(sourceQuery.shouldMaintainCache());
}
// For flashback: Read attributes as of the same time if required.
if (((ObjectLevelReadQuery)sourceQuery).hasAsOfClause()) {
targetQuery.setSelectionCriteria((Expression)targetQuery.getSelectionCriteria().clone());
((ObjectLevelReadQuery)targetQuery).setAsOfClause(((ObjectLevelReadQuery)sourceQuery).getAsOfClause());
}
}
if (isExtendingPessimisticLockScope(sourceQuery)) {
if (this.extendPessimisticLockScope == ExtendPessimisticLockScope.TARGET_QUERY) {
if (targetQuery == this.selectionQuery) {
// perf: bug#4751950, first prepare the query before cloning.
if (targetQuery.shouldPrepare()) {
targetQuery.checkPrepare(executionSession, row);
}
targetQuery = (ObjectLevelReadQuery)targetQuery.clone();
targetQuery.setIsExecutionClone(true);
}
extendPessimisticLockScopeInTargetQuery((ObjectLevelReadQuery)targetQuery, sourceQuery);
} else if (this.extendPessimisticLockScope == ExtendPessimisticLockScope.DEDICATED_QUERY) {
ReadQuery dedicatedQuery = getExtendPessimisticLockScopeDedicatedQuery(executionSession, sourceQuery.getLockMode());
executionSession.executeQuery(dedicatedQuery, row);
}
}
}
targetQuery = prepareHistoricalQuery(targetQuery, sourceQuery, executionSession);