Search in sources :

Example 1 with ThreadCursoredList

use of org.eclipse.persistence.internal.helper.ThreadCursoredList in project eclipselink by eclipse-ee4j.

the class DatabaseAccessor method basicExecuteCall.

/**
 * Execute the call.
 * The execution can differ slightly depending on the type of call.
 * The call may be parameterized where the arguments are in the translation row.
 * The row will be empty if there are no parameters.
 * @return depending of the type either the row count, row or vector of rows.
 */
public Object basicExecuteCall(Call call, AbstractRecord translationRow, AbstractSession session, boolean batch) throws DatabaseException {
    Statement statement = null;
    Object result = null;
    DatabaseCall dbCall = null;
    // only used if this is a read query
    ResultSet resultSet = null;
    try {
        dbCall = (DatabaseCall) call;
    } catch (ClassCastException e) {
        throw QueryException.invalidDatabaseCall(call);
    }
    // If the login is null, then this accessor has never been connected.
    if (this.login == null) {
        throw DatabaseException.databaseAccessorNotConnected();
    }
    if (batch && isInBatchWritingMode(session)) {
        // we may want to refactor this some day
        if (dbCall.isBatchExecutionSupported()) {
            // this will handle executing batched statements, or switching mechanisms if required
            getActiveBatchWritingMechanism(session).appendCall(session, dbCall);
            // is no way to know if it succeeded on the DB at this point.
            return 1;
        } else {
            getActiveBatchWritingMechanism(session).executeBatchedStatements(session);
        }
    }
    try {
        incrementCallCount(session);
        if (session.shouldLog(SessionLog.FINE, SessionLog.SQL)) {
            // Avoid printing if no logging required.
            session.log(SessionLog.FINE, SessionLog.SQL, dbCall.getLogString(this), null, this, false);
        }
        session.startOperationProfile(SessionProfiler.SqlPrepare, dbCall.getQuery(), SessionProfiler.ALL);
        try {
            statement = dbCall.prepareStatement(this, translationRow, session);
        } finally {
            session.endOperationProfile(SessionProfiler.SqlPrepare, dbCall.getQuery(), SessionProfiler.ALL);
        }
        // effectively this means that someone is executing an update type query.
        if (dbCall.isExecuteUpdate()) {
            dbCall.setExecuteReturnValue(execute(dbCall, statement, session));
            dbCall.setStatement(statement);
            this.possibleFailure = false;
            return dbCall;
        } else if (dbCall.isNothingReturned()) {
            result = executeNoSelect(dbCall, statement, session);
            this.writeStatementsCount++;
            if (dbCall.isLOBLocatorNeeded()) {
                // add original (insert or update) call to the LOB locator
                // Bug 2804663 - LOBValueWriter is no longer a singleton
                getLOBWriter().addCall(dbCall);
            }
        } else if ((!dbCall.getReturnsResultSet() || (dbCall.getReturnsResultSet() && dbCall.shouldBuildOutputRow()))) {
            result = session.getPlatform().executeStoredProcedure(dbCall, (PreparedStatement) statement, this, session);
            this.storedProcedureStatementsCount++;
        } else {
            resultSet = executeSelect(dbCall, statement, session);
            this.readStatementsCount++;
            if (!dbCall.shouldIgnoreFirstRowSetting() && dbCall.getFirstResult() != 0) {
                resultSet.absolute(dbCall.getFirstResult());
            }
            dbCall.matchFieldOrder(resultSet, this, session);
            if (dbCall.isCursorReturned()) {
                dbCall.setStatement(statement);
                dbCall.setResult(resultSet);
                this.possibleFailure = false;
                return dbCall;
            }
            result = processResultSet(resultSet, dbCall, statement, session);
        }
        if (result instanceof ThreadCursoredList) {
            this.possibleFailure = false;
            return result;
        }
        // Log any warnings on finest.
        if (session.shouldLog(SessionLog.FINEST, SessionLog.SQL)) {
            // Avoid printing if no logging required.
            SQLWarning warning = statement.getWarnings();
            while (warning != null) {
                String message = warning.getMessage() + ":" + warning.getSQLState() + " - " + warning.getCause();
                // 325605: This log will not be tracked by QuerySQLTracker
                session.log(SessionLog.FINEST, SessionLog.SQL, message, null, this, false);
                warning = warning.getNextWarning();
            }
        }
    } catch (SQLException exception) {
        // If this is a connection from an external pool then closeStatement will close the connection.
        // we must test the connection before that happens.
        RuntimeException exceptionToThrow = processExceptionForCommError(session, exception, dbCall);
        try {
            // Ensure that the statement is closed, but still ensure that the real exception is thrown.
            closeStatement(statement, session, dbCall);
        } catch (Exception closeException) {
        }
        if (exceptionToThrow == null) {
            // not a comm failure :
            throw DatabaseException.sqlException(exception, dbCall, this, session, false);
        }
        throw exceptionToThrow;
    } catch (RuntimeException exception) {
        try {
            // Ensure that the statement is closed, but still ensure that the real exception is thrown.
            closeStatement(statement, session, dbCall);
        } catch (Exception closeException) {
        }
        if (exception instanceof DatabaseException) {
            ((DatabaseException) exception).setCall(dbCall);
            if (((DatabaseException) exception).getAccessor() == null) {
                ((DatabaseException) exception).setAccessor(this);
            }
        }
        throw exception;
    }
    // This is in a separate try block to ensure that the real exception is not masked by the close exception.
    try {
        // Allow for caching of statement, forced closes are not cache as they failed execution so are most likely bad.
        releaseStatement(statement, dbCall.getSQLString(), dbCall, session);
    } catch (SQLException exception) {
        // With an external connection pool the connection may be null after this call, if it is we will
        // be unable to determine if it is a connection based exception so treat it as if it wasn't.
        DatabaseException commException = processExceptionForCommError(session, exception, null);
        if (commException != null) {
            throw commException;
        }
        throw DatabaseException.sqlException(exception, this, session, false);
    }
    this.possibleFailure = false;
    return result;
}
Also used : SQLWarning(java.sql.SQLWarning) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) ThreadCursoredList(org.eclipse.persistence.internal.helper.ThreadCursoredList) PreparedStatement(java.sql.PreparedStatement) SQLException(java.sql.SQLException) DatabaseException(org.eclipse.persistence.exceptions.DatabaseException) IOException(java.io.IOException) QueryException(org.eclipse.persistence.exceptions.QueryException) ResultSet(java.sql.ResultSet) DatabaseException(org.eclipse.persistence.exceptions.DatabaseException)

Example 2 with ThreadCursoredList

use of org.eclipse.persistence.internal.helper.ThreadCursoredList in project eclipselink by eclipse-ee4j.

the class ReadAllQuery method executeObjectLevelReadQuery.

/**
 * INTERNAL:
 * Execute the query.
 * Get the rows and build the object from the rows.
 * @exception  DatabaseException - an error has occurred on the database
 * @return java.lang.Object collection of objects resulting from execution of query.
 */
@Override
protected Object executeObjectLevelReadQuery() throws DatabaseException {
    Object result = null;
    if (this.containerPolicy.overridesRead()) {
        this.executionTime = System.currentTimeMillis();
        return this.containerPolicy.execute();
    }
    if (this.descriptor.isDescriptorForInterface()) {
        Object returnValue = this.descriptor.getInterfacePolicy().selectAllObjectsUsingMultipleTableSubclassRead(this);
        this.executionTime = System.currentTimeMillis();
        return returnValue;
    }
    if (this.descriptor.hasTablePerClassPolicy() && this.descriptor.isAbstract()) {
        result = this.containerPolicy.containerInstance();
        if (this.shouldIncludeData) {
            ComplexQueryResult complexResult = new ComplexQueryResult();
            complexResult.setResult(result);
            complexResult.setData(new ArrayList());
            result = complexResult;
        }
    } else {
        Object sopObject = getTranslationRow().getSopObject();
        boolean useOptimization = false;
        if (sopObject == null) {
            useOptimization = usesResultSetAccessOptimization();
        }
        if (useOptimization) {
            DatabaseCall call = ((DatasourceCallQueryMechanism) this.queryMechanism).selectResultSet();
            this.executionTime = System.currentTimeMillis();
            Statement statement = call.getStatement();
            ResultSet resultSet = call.getResult();
            DatabaseAccessor dbAccessor = (DatabaseAccessor) getAccessor();
            boolean exceptionOccured = false;
            try {
                if (this.session.isUnitOfWork()) {
                    result = registerResultSetInUnitOfWork(resultSet, call.getFields(), call.getFieldsArray(), (UnitOfWorkImpl) this.session, this.translationRow);
                } else {
                    result = this.containerPolicy.containerInstance();
                    this.descriptor.getObjectBuilder().buildObjectsFromResultSetInto(this, resultSet, call.getFields(), call.getFieldsArray(), result);
                }
            } catch (SQLException exception) {
                exceptionOccured = true;
                DatabaseException commException = dbAccessor.processExceptionForCommError(this.session, exception, call);
                if (commException != null) {
                    throw commException;
                }
                throw DatabaseException.sqlException(exception, call, dbAccessor, this.session, false);
            } finally {
                try {
                    if (resultSet != null) {
                        resultSet.close();
                    }
                    if (dbAccessor != null) {
                        if (statement != null) {
                            dbAccessor.releaseStatement(statement, call.getSQLString(), call, this.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, this.session, false);
                    }
                }
            }
        } else {
            List<AbstractRecord> rows;
            if (sopObject != null) {
                Object valuesIterator = this.containerPolicy.iteratorFor(getTranslationRow().getSopObject());
                int size = this.containerPolicy.sizeFor(sopObject);
                rows = new ArrayList<>(size);
                while (this.containerPolicy.hasNext(valuesIterator)) {
                    Object memberSopObject = this.containerPolicy.next(valuesIterator, this.session);
                    DatabaseRecord memberRow = new DatabaseRecord(0);
                    memberRow.setSopObject(memberSopObject);
                    rows.add(memberRow);
                }
                this.executionTime = System.currentTimeMillis();
            } else {
                rows = getQueryMechanism().selectAllRows();
                this.executionTime = System.currentTimeMillis();
                // If using 1-m joins, must set all rows.
                if (hasJoining() && this.joinedAttributeManager.isToManyJoin()) {
                    this.joinedAttributeManager.setDataResults(rows, this.session);
                }
                // Batch fetching in IN requires access to the rows to build the id array.
                if ((this.batchFetchPolicy != null) && this.batchFetchPolicy.isIN()) {
                    this.batchFetchPolicy.setDataResults(rows);
                }
            }
            if (this.session.isUnitOfWork()) {
                // 
                result = registerResultInUnitOfWork(rows, (UnitOfWorkImpl) this.session, this.translationRow, true);
            } else {
                if (rows instanceof ThreadCursoredList) {
                    result = this.containerPolicy.containerInstance();
                } else {
                    result = this.containerPolicy.containerInstance(rows.size());
                }
                this.descriptor.getObjectBuilder().buildObjectsInto(this, rows, result);
            }
            if (sopObject != null) {
                if (!this.descriptor.getObjectBuilder().isSimple()) {
                    // remove sopObject so it's not stuck in any value holder.
                    for (AbstractRecord row : rows) {
                        row.setSopObject(null);
                    }
                }
            } else {
                if (this.shouldIncludeData) {
                    ComplexQueryResult complexResult = new ComplexQueryResult();
                    complexResult.setResult(result);
                    complexResult.setData(rows);
                    result = complexResult;
                }
            }
        }
    }
    // Add the other (already registered) results and return them.
    if (this.descriptor.hasTablePerClassPolicy()) {
        result = this.containerPolicy.concatenateContainers(result, this.descriptor.getTablePerClassPolicy().selectAllObjectsUsingMultipleTableSubclassRead(this), this.session);
    }
    // If the results were empty, then ensure they get cached still.
    if (shouldCacheQueryResults() && this.containerPolicy.isEmpty(result)) {
        this.temporaryCachedQueryResults = InvalidObject.instance();
    }
    return result;
}
Also used : DatabaseRecord(org.eclipse.persistence.sessions.DatabaseRecord) SQLException(java.sql.SQLException) Statement(java.sql.Statement) ThreadCursoredList(org.eclipse.persistence.internal.helper.ThreadCursoredList) DatasourceCallQueryMechanism(org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism) ArrayList(java.util.ArrayList) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) UnitOfWorkImpl(org.eclipse.persistence.internal.sessions.UnitOfWorkImpl) DatabaseCall(org.eclipse.persistence.internal.databaseaccess.DatabaseCall) ResultSet(java.sql.ResultSet) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) DatabaseAccessor(org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor) DatabaseException(org.eclipse.persistence.exceptions.DatabaseException)

Example 3 with ThreadCursoredList

use of org.eclipse.persistence.internal.helper.ThreadCursoredList 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;
}
Also used : ThreadCursoredList(org.eclipse.persistence.internal.helper.ThreadCursoredList) JoinedAttributeManager(org.eclipse.persistence.internal.queries.JoinedAttributeManager) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord) ArrayList(java.util.ArrayList) ContainerPolicy(org.eclipse.persistence.internal.queries.ContainerPolicy) InheritancePolicy(org.eclipse.persistence.descriptors.InheritancePolicy) Collection(java.util.Collection) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) ThreadCursoredList(org.eclipse.persistence.internal.helper.ThreadCursoredList) ArrayList(java.util.ArrayList) List(java.util.List) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Aggregations

ThreadCursoredList (org.eclipse.persistence.internal.helper.ThreadCursoredList)3 ResultSet (java.sql.ResultSet)2 SQLException (java.sql.SQLException)2 Statement (java.sql.Statement)2 ArrayList (java.util.ArrayList)2 DatabaseException (org.eclipse.persistence.exceptions.DatabaseException)2 InvalidObject (org.eclipse.persistence.internal.helper.InvalidObject)2 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)2 IOException (java.io.IOException)1 CallableStatement (java.sql.CallableStatement)1 PreparedStatement (java.sql.PreparedStatement)1 SQLWarning (java.sql.SQLWarning)1 Collection (java.util.Collection)1 List (java.util.List)1 InheritancePolicy (org.eclipse.persistence.descriptors.InheritancePolicy)1 QueryException (org.eclipse.persistence.exceptions.QueryException)1 DatabaseAccessor (org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor)1 DatabaseCall (org.eclipse.persistence.internal.databaseaccess.DatabaseCall)1 ContainerPolicy (org.eclipse.persistence.internal.queries.ContainerPolicy)1 DatasourceCallQueryMechanism (org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism)1