Search in sources :

Example 1 with SimpleResultSetRecord

use of org.eclipse.persistence.internal.sessions.SimpleResultSetRecord in project eclipselink by eclipse-ee4j.

the class ReadAllQuery method registerResultSetInUnitOfWork.

/**
 * INTERNAL:
 * Version of the previous method for ResultSet optimization.
 *
 * @return the final (conformed, refreshed, wrapped) UnitOfWork query result
 */
public Object registerResultSetInUnitOfWork(ResultSet resultSet, Vector fields, DatabaseField[] fieldsArray, UnitOfWorkImpl unitOfWork, AbstractRecord arguments) throws SQLException {
    // TODO: add support for Conforming results in UOW - currently conforming in uow is not compatible with ResultSet optimization.
    ContainerPolicy cp = this.containerPolicy;
    Object clones = cp.containerInstance();
    ResultSetMetaData metaData = resultSet.getMetaData();
    boolean hasNext = resultSet.next();
    if (hasNext) {
        // TODO: possibly add support for SortedListContainerPolicy (cp.shouldAddAll() == true) - this policy currently is not compatible with ResultSet optimization
        boolean quickAdd = (clones instanceof Collection) && !this.descriptor.getObjectBuilder().hasWrapperPolicy();
        DatabaseAccessor dbAccessor = (DatabaseAccessor) getAccessor();
        boolean useSimple = this.descriptor.getObjectBuilder().isSimple();
        AbstractSession executionSession = getExecutionSession();
        DatabasePlatform platform = dbAccessor.getPlatform();
        boolean optimizeData = platform.shouldOptimizeDataConversion();
        if (useSimple) {
            // None of the fields are relational - the row could be reused, just clear all the values.
            SimpleResultSetRecord row = new SimpleResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, platform, optimizeData);
            if (this.descriptor.isDescriptorTypeAggregate()) {
                // Aggregate Collection may have an unmapped primary key referencing the owner, the corresponding field will not be used when the object is populated and therefore may not be cleared.
                row.setShouldKeepValues(true);
            }
            while (hasNext) {
                Object clone = buildObject(row);
                if (quickAdd) {
                    ((Collection) clones).add(clone);
                } else {
                    // TODO: investigate is it possible to support MappedKeyMapPolicy - this policy currently is not compatible with ResultSet optimization
                    cp.addInto(clone, clones, unitOfWork);
                }
                row.reset();
                hasNext = resultSet.next();
            }
        } else {
            boolean shouldKeepRow = this.descriptor.getObjectBuilder().shouldKeepRow();
            while (hasNext) {
                ResultSetRecord row = new ResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, platform, optimizeData);
                Object clone = buildObject(row);
                if (quickAdd) {
                    ((Collection) clones).add(clone);
                } else {
                    // TODO: investigate is it possible to support MappedKeyMapPolicy - this policy currently is not compatible with ResultSet optimization
                    cp.addInto(clone, clones, unitOfWork);
                }
                if (shouldKeepRow) {
                    if (row.hasResultSet()) {
                        // ResultSet has not been fully triggered - that means the cached object was used.
                        // Yet the row still may be cached in a value holder (see loadBatchReadAttributes and loadJoinedAttributes methods).
                        // Remove ResultSet to avoid attempt to trigger it (already closed) when pk or fk values (already extracted) accessed when the value holder is instantiated.
                        row.removeResultSet();
                    } else {
                        row.removeNonIndirectionValues();
                    }
                }
                hasNext = resultSet.next();
            }
        }
    }
    return clones;
}
Also used : ResultSetMetaData(java.sql.ResultSetMetaData) ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) Collection(java.util.Collection) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) DatabaseAccessor(org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor) SimpleResultSetRecord(org.eclipse.persistence.internal.sessions.SimpleResultSetRecord) ResultSetRecord(org.eclipse.persistence.internal.sessions.ResultSetRecord) DatabasePlatform(org.eclipse.persistence.internal.databaseaccess.DatabasePlatform) SimpleResultSetRecord(org.eclipse.persistence.internal.sessions.SimpleResultSetRecord) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 2 with SimpleResultSetRecord

use of org.eclipse.persistence.internal.sessions.SimpleResultSetRecord in project eclipselink by eclipse-ee4j.

the class ReadObjectQuery method executeObjectLevelReadQuery.

/**
 * INTERNAL:
 * Execute the query.
 * Do a cache lookup and build object from row if required.
 * @exception  DatabaseException - an error has occurred on the database
 * @return object - the first object found or null if none.
 */
@Override
protected Object executeObjectLevelReadQuery() throws DatabaseException {
    if (this.descriptor.isDescriptorForInterface() || this.descriptor.hasTablePerClassPolicy()) {
        Object returnValue = this.descriptor.getInterfacePolicy().selectOneObjectUsingMultipleTableSubclassRead(this);
        if (this.descriptor.hasTablePerClassPolicy() && (!this.descriptor.isAbstract()) && (returnValue == null)) {
        // let it fall through to query the root.
        } else {
            this.executionTime = System.currentTimeMillis();
            return returnValue;
        }
    }
    boolean shouldSetRowsForJoins = hasJoining() && this.joinedAttributeManager.isToManyJoin();
    AbstractSession session = getSession();
    Object result = null;
    AbstractRecord row = null;
    Object sopObject = getTranslationRow().getSopObject();
    boolean useOptimization = false;
    if (sopObject == null) {
        useOptimization = usesResultSetAccessOptimization();
    }
    if (useOptimization) {
        DatabaseCall call = ((DatasourceCallQueryMechanism) this.queryMechanism).selectResultSet();
        this.executionTime = System.currentTimeMillis();
        boolean exceptionOccured = false;
        ResultSet resultSet = call.getResult();
        DatabaseAccessor dbAccessor = (DatabaseAccessor) getAccessor();
        try {
            if (resultSet.next()) {
                ResultSetMetaData metaData = call.getResult().getMetaData();
                boolean useSimple = this.descriptor.getObjectBuilder().isSimple();
                DatabasePlatform platform = dbAccessor.getPlatform();
                boolean optimizeData = platform.shouldOptimizeDataConversion();
                if (useSimple) {
                    row = new SimpleResultSetRecord(call.getFields(), call.getFieldsArray(), resultSet, metaData, dbAccessor, getExecutionSession(), platform, optimizeData);
                    if (this.descriptor.isDescriptorTypeAggregate()) {
                        // Aggregate Collection may have an unmapped primary key referencing the owner, the corresponding field will not be used when the object is populated and therefore may not be cleared.
                        ((SimpleResultSetRecord) row).setShouldKeepValues(true);
                    }
                } else {
                    row = new ResultSetRecord(call.getFields(), call.getFieldsArray(), resultSet, metaData, dbAccessor, getExecutionSession(), platform, optimizeData);
                }
                if (session.isUnitOfWork()) {
                    result = registerResultInUnitOfWork(row, (UnitOfWorkImpl) session, this.translationRow, true);
                } else {
                    result = buildObject(row);
                }
                if (!useSimple && this.descriptor.getObjectBuilder().shouldKeepRow()) {
                    if (((ResultSetRecord) row).hasResultSet()) {
                        // ResultSet has not been fully triggered - that means the cached object was used.
                        // Yet the row still may be cached in a value holder (see loadBatchReadAttributes and loadJoinedAttributes methods).
                        // Remove ResultSet to avoid attempt to trigger it (already closed) when pk or fk values (already extracted) accessed when the value holder is instantiated.
                        ((ResultSetRecord) row).removeResultSet();
                    } else {
                        ((ResultSetRecord) row).removeNonIndirectionValues();
                    }
                }
            }
        } catch (SQLException exception) {
            exceptionOccured = true;
            DatabaseException commException = dbAccessor.processExceptionForCommError(session, exception, call);
            if (commException != null) {
                throw commException;
            }
            throw DatabaseException.sqlException(exception, call, getAccessor(), session, false);
        } finally {
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (dbAccessor != null) {
                    if (call.getStatement() != null) {
                        dbAccessor.releaseStatement(call.getStatement(), call.getSQLString(), call, session);
                    }
                }
                if (call.hasAllocatedConnection()) {
                    getExecutionSession().releaseConnectionAfterCall(this);
                }
            } catch (RuntimeException cleanupException) {
                if (!exceptionOccured) {
                    throw cleanupException;
                }
            } catch (SQLException cleanupSQLException) {
                if (!exceptionOccured) {
                    throw DatabaseException.sqlException(cleanupSQLException, call, dbAccessor, session, false);
                }
            }
        }
    } else {
        if (sopObject != null) {
            row = new DatabaseRecord(0);
            row.setSopObject(sopObject);
        } else {
            // If using 1-m joins, must select all rows.
            if (shouldSetRowsForJoins) {
                List rows = getQueryMechanism().selectAllRows();
                if (rows.size() > 0) {
                    row = (AbstractRecord) rows.get(0);
                }
                getJoinedAttributeManager().setDataResults(rows, session);
            } else {
                row = getQueryMechanism().selectOneRow();
            }
        }
        this.executionTime = System.currentTimeMillis();
        if (row != null) {
            if (session.isUnitOfWork()) {
                result = registerResultInUnitOfWork(row, (UnitOfWorkImpl) session, this.translationRow, true);
            } else {
                result = buildObject(row);
            }
            if (sopObject != null) {
                // remove sopObject so it's not stuck in a value holder.
                row.setSopObject(null);
            }
        }
    }
    if ((result == null) && shouldCacheQueryResults()) {
        cacheResult(null);
    }
    if ((result == null) && this.shouldRefreshIdentityMapResult) {
        // bug5955326, should invalidate the shared cached if refreshed object no longer exists.
        if (this.selectionId != null) {
            session.getParentIdentityMapSession(this.descriptor, true, true).getIdentityMapAccessor().invalidateObject(this.selectionId, this.referenceClass);
        } else if (this.selectionObject != null) {
            session.getParentIdentityMapSession(this.descriptor, true, true).getIdentityMapAccessor().invalidateObject(this.selectionObject);
        }
    }
    if (this.shouldIncludeData && (sopObject == null)) {
        ComplexQueryResult complexResult = new ComplexQueryResult();
        complexResult.setResult(result);
        complexResult.setData(row);
        return complexResult;
    }
    return result;
}
Also used : DatabaseRecord(org.eclipse.persistence.sessions.DatabaseRecord) SQLException(java.sql.SQLException) DatasourceCallQueryMechanism(org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) UnitOfWorkImpl(org.eclipse.persistence.internal.sessions.UnitOfWorkImpl) SimpleResultSetRecord(org.eclipse.persistence.internal.sessions.SimpleResultSetRecord) ResultSetRecord(org.eclipse.persistence.internal.sessions.ResultSetRecord) DatabasePlatform(org.eclipse.persistence.internal.databaseaccess.DatabasePlatform) SimpleResultSetRecord(org.eclipse.persistence.internal.sessions.SimpleResultSetRecord) DatabaseCall(org.eclipse.persistence.internal.databaseaccess.DatabaseCall) ResultSetMetaData(java.sql.ResultSetMetaData) ResultSet(java.sql.ResultSet) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) DatabaseAccessor(org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor) List(java.util.List) DatabaseException(org.eclipse.persistence.exceptions.DatabaseException) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 3 with SimpleResultSetRecord

use of org.eclipse.persistence.internal.sessions.SimpleResultSetRecord in project eclipselink by eclipse-ee4j.

the class ObjectBuilder method buildObjectsFromResultSetInto.

/**
 * Version of buildObjectsInto method that takes call instead of rows.
 * Return a container which contains the instances of the receivers javaClass.
 * Set the fields of the instance to the values stored in the result set.
 */
public Object buildObjectsFromResultSetInto(ReadAllQuery query, ResultSet resultSet, Vector fields, DatabaseField[] fieldsArray, Object domainObjects) throws SQLException {
    AbstractSession session = query.getSession();
    session.startOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
    try {
        boolean hasNext = resultSet.next();
        if (hasNext) {
            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();
            // !cp.shouldAddAll() - query with SortedListContainerPolicy - currently does not use this method
            boolean quickAdd = (domainObjects instanceof Collection) && !this.hasWrapperPolicy;
            ResultSetMetaData metaData = resultSet.getMetaData();
            ResultSetRecord row = null;
            AbstractSession executionSession = query.getExecutionSession();
            DatabaseAccessor dbAccessor = (DatabaseAccessor) query.getAccessor();
            DatabasePlatform platform = dbAccessor.getPlatform();
            boolean optimizeData = platform.shouldOptimizeDataConversion();
            if (this.isSimple) {
                // None of the fields are relational - the row could be reused, just clear all the values.
                row = new SimpleResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, platform, optimizeData);
                if (this.descriptor.isDescriptorTypeAggregate()) {
                    // Aggregate Collection may have an unmapped primary key referencing the owner, the corresponding field will not be used when the object is populated and therefore may not be cleared.
                    ((SimpleResultSetRecord) row).setShouldKeepValues(true);
                }
            }
            while (hasNext) {
                if (!this.isSimple) {
                    row = new ResultSetRecord(fields, fieldsArray, resultSet, metaData, dbAccessor, executionSession, platform, optimizeData);
                }
                Object domainObject = buildObject(query, row, joinManager, session, this.descriptor, inheritancePolicy, isUnitOfWork, shouldCacheQueryResults, shouldUseWrapperPolicy);
                if (quickAdd) {
                    ((Collection) domainObjects).add(domainObject);
                } else {
                    // query with MappedKeyMapPolicy currently does not use this method
                    policy.addInto(domainObject, domainObjects, session);
                }
                if (this.isSimple) {
                    ((SimpleResultSetRecord) row).reset();
                } else {
                    if (this.shouldKeepRow) {
                        if (row.hasResultSet()) {
                            // ResultSet has not been fully triggered - that means the cached object was used.
                            // Yet the row still may be cached in a value holder (see loadBatchReadAttributes and loadJoinedAttributes methods).
                            // Remove ResultSet to avoid attempt to trigger it (already closed) when pk or fk values (already extracted) accessed when the value holder is instantiated.
                            row.removeResultSet();
                        } else {
                            row.removeNonIndirectionValues();
                        }
                    }
                }
                hasNext = resultSet.next();
            }
        }
    } finally {
        session.endOperationProfile(SessionProfiler.ObjectBuilding, query, SessionProfiler.ALL);
    }
    return domainObjects;
}
Also used : ResultSetMetaData(java.sql.ResultSetMetaData) ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) InheritancePolicy(org.eclipse.persistence.descriptors.InheritancePolicy) JoinedAttributeManager(org.eclipse.persistence.internal.queries.JoinedAttributeManager) Collection(java.util.Collection) SimpleResultSetRecord(org.eclipse.persistence.internal.sessions.SimpleResultSetRecord) ResultSetRecord(org.eclipse.persistence.internal.sessions.ResultSetRecord) DatabaseAccessor(org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) DatabasePlatform(org.eclipse.persistence.internal.databaseaccess.DatabasePlatform) SimpleResultSetRecord(org.eclipse.persistence.internal.sessions.SimpleResultSetRecord) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Aggregations

ResultSetMetaData (java.sql.ResultSetMetaData)3 DatabaseAccessor (org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor)3 DatabasePlatform (org.eclipse.persistence.internal.databaseaccess.DatabasePlatform)3 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)3 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)3 ResultSetRecord (org.eclipse.persistence.internal.sessions.ResultSetRecord)3 SimpleResultSetRecord (org.eclipse.persistence.internal.sessions.SimpleResultSetRecord)3 Collection (java.util.Collection)2 ContainerPolicy (org.eclipse.persistence.internal.queries.ContainerPolicy)2 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 List (java.util.List)1 InheritancePolicy (org.eclipse.persistence.descriptors.InheritancePolicy)1 DatabaseException (org.eclipse.persistence.exceptions.DatabaseException)1 DatabaseCall (org.eclipse.persistence.internal.databaseaccess.DatabaseCall)1 DatasourceCallQueryMechanism (org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism)1 JoinedAttributeManager (org.eclipse.persistence.internal.queries.JoinedAttributeManager)1 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)1 UnitOfWorkImpl (org.eclipse.persistence.internal.sessions.UnitOfWorkImpl)1 DatabaseRecord (org.eclipse.persistence.sessions.DatabaseRecord)1