Search in sources :

Example 26 with DatabaseCall

use of org.eclipse.persistence.internal.databaseaccess.DatabaseCall in project eclipselink by eclipse-ee4j.

the class ReadAllQuery method executeObjectLevelReadQueryFromResultSet.

/**
 * INTERNAL:
 * Execute the query building the objects directly from the database result-set.
 * @exception  DatabaseException - an error has occurred on the database
 * @return an ArrayList of the resulting objects.
 */
@Override
protected Object executeObjectLevelReadQueryFromResultSet() throws DatabaseException {
    AbstractSession session = this.session;
    DatabasePlatform platform = session.getPlatform();
    DatabaseCall call = ((DatasourceCallQueryMechanism) this.queryMechanism).selectResultSet();
    Statement statement = call.getStatement();
    ResultSet resultSet = call.getResult();
    DatabaseAccessor accessor = (DatabaseAccessor) getAccessor();
    boolean exceptionOccured = false;
    try {
        ResultSetMetaData metaData = resultSet.getMetaData();
        List results = new ArrayList();
        ObjectBuilder builder = this.descriptor.getObjectBuilder();
        while (resultSet.next()) {
            results.add(builder.buildObjectFromResultSet(this, this.joinedAttributeManager, resultSet, session, accessor, metaData, platform, call.getFields(), call.getFieldsArray()));
        }
        return results;
    } catch (SQLException exception) {
        exceptionOccured = true;
        DatabaseException commException = accessor.processExceptionForCommError(session, exception, call);
        if (commException != null) {
            throw commException;
        }
        throw DatabaseException.sqlException(exception, call, accessor, session, false);
    } finally {
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                accessor.releaseStatement(statement, call.getSQLString(), call, session);
            }
            if (accessor != null) {
                session.releaseReadConnection(accessor);
            }
        } catch (SQLException exception) {
            if (!exceptionOccured) {
                // in the case of an external connection pool the connection may be null after the statement release
                // if it is null we will be unable to check the connection for a comm error and
                // therefore must return as if it was not a comm error.
                DatabaseException commException = accessor.processExceptionForCommError(session, exception, call);
                if (commException != null) {
                    throw commException;
                }
                throw DatabaseException.sqlException(exception, call, accessor, session, false);
            }
        }
    }
}
Also used : SQLException(java.sql.SQLException) Statement(java.sql.Statement) DatasourceCallQueryMechanism(org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism) ArrayList(java.util.ArrayList) DatabasePlatform(org.eclipse.persistence.internal.databaseaccess.DatabasePlatform) ObjectBuilder(org.eclipse.persistence.internal.descriptors.ObjectBuilder) DatabaseCall(org.eclipse.persistence.internal.databaseaccess.DatabaseCall) ResultSetMetaData(java.sql.ResultSetMetaData) ResultSet(java.sql.ResultSet) DatabaseAccessor(org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor) ThreadCursoredList(org.eclipse.persistence.internal.helper.ThreadCursoredList) ArrayList(java.util.ArrayList) List(java.util.List) DatabaseException(org.eclipse.persistence.exceptions.DatabaseException) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 27 with DatabaseCall

use of org.eclipse.persistence.internal.databaseaccess.DatabaseCall 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 28 with DatabaseCall

use of org.eclipse.persistence.internal.databaseaccess.DatabaseCall in project eclipselink by eclipse-ee4j.

the class ReadQuery method prepareForExecution.

/**
 * INTERNAL:
 * Prepare the receiver for execution in a session.
 */
@Override
public void prepareForExecution() throws QueryException {
    super.prepareForExecution();
    DatabaseCall databaseCall = this.getCall();
    if (databaseCall != null && (databaseCall.shouldIgnoreFirstRowSetting() || databaseCall.shouldIgnoreMaxResultsSetting())) {
        AbstractRecord parameters = this.getTranslationRow();
        if (parameters.isEmpty()) {
            parameters = new DatabaseRecord();
        }
        // We should check FirstRow and MaxResults separately.
        if (databaseCall.shouldIgnoreFirstRowSetting()) {
            parameters.add(DatabaseCall.FIRSTRESULT_FIELD, this.getFirstResult());
        }
        if (databaseCall.shouldIgnoreMaxResultsSetting()) {
            // Bug #493771
            parameters.add(DatabaseCall.MAXROW_FIELD, ((DatabasePlatform) session.getPlatform(databaseCall.getQuery().getReferenceClass())).computeMaxRowsForSQL(this.getFirstResult(), this.getMaxRows()));
        }
        this.setTranslationRow(parameters);
    }
}
Also used : DatabaseCall(org.eclipse.persistence.internal.databaseaccess.DatabaseCall) DatabaseRecord(org.eclipse.persistence.sessions.DatabaseRecord) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord)

Example 29 with DatabaseCall

use of org.eclipse.persistence.internal.databaseaccess.DatabaseCall in project eclipselink by eclipse-ee4j.

the class ResultSetMappingQuery method executeDatabaseQuery.

/**
 * INTERNAL:
 * Executes the prepared query on the datastore.
 */
@Override
public Object executeDatabaseQuery() throws DatabaseException {
    if (getSession().isUnitOfWork()) {
        UnitOfWorkImpl unitOfWork = (UnitOfWorkImpl) getSession();
        // transaction early on the parent also.
        if (isLockQuery()) {
            if ((!unitOfWork.getCommitManager().isActive()) && (!unitOfWork.wasTransactionBegunPrematurely())) {
                unitOfWork.beginTransaction();
                unitOfWork.setWasTransactionBegunPrematurely(true);
            }
        }
        if (unitOfWork.isNestedUnitOfWork()) {
            // execute in parent UOW then register normally here.
            UnitOfWorkImpl nestedUnitOfWork = (UnitOfWorkImpl) getSession();
            setSession(nestedUnitOfWork.getParent());
            Object result = executeDatabaseQuery();
            setSession(nestedUnitOfWork);
            Object clone = registerIndividualResult(result, null, unitOfWork, null, null);
            if (shouldUseWrapperPolicy()) {
                clone = getDescriptor().getObjectBuilder().wrapObject(clone, unitOfWork);
            }
            return clone;
        }
    }
    // this will update the query with any settings
    session.validateQuery(this);
    if (getQueryId() == 0) {
        setQueryId(getSession().getNextQueryId());
    }
    if (getCall().isExecuteUpdate()) {
        DatabaseCall call = ((StoredProcedureCall) getQueryMechanism().execute());
        setExecutionTime(System.currentTimeMillis());
        return call;
    } else {
        Vector rows = getQueryMechanism().executeSelect();
        setExecutionTime(System.currentTimeMillis());
        // If using 1-m joins, must set all rows.
        return buildObjectsFromRecords(rows);
    }
}
Also used : DatabaseCall(org.eclipse.persistence.internal.databaseaccess.DatabaseCall) UnitOfWorkImpl(org.eclipse.persistence.internal.sessions.UnitOfWorkImpl) Vector(java.util.Vector)

Example 30 with DatabaseCall

use of org.eclipse.persistence.internal.databaseaccess.DatabaseCall in project eclipselink by eclipse-ee4j.

the class ExpressionQueryMechanism method selectOneRowFromConcreteTable.

/**
 * Read a single row from the database.
 * This is used from query  mechanism during an abstract-multiple table read.
 */
public AbstractRecord selectOneRowFromConcreteTable() throws DatabaseException {
    ObjectLevelReadQuery query = (ObjectLevelReadQuery) this.query;
    // PERF: First check the subclass calls cache for the prepared call.
    // Must clear the translation row to avoid in-lining parameters unless not a prepared query.
    boolean shouldPrepare = query.shouldPrepare();
    DatabaseCall call = null;
    if (shouldPrepare) {
        call = query.getConcreteSubclassCalls().get(query.getReferenceClass());
    }
    if (call == null) {
        AbstractRecord translationRow = query.getTranslationRow();
        if (shouldPrepare) {
            query.setTranslationRow(null);
        }
        setSQLStatement(buildConcreteSelectStatement());
        // Must also build the call.
        super.prepareSelectOneRow();
        if (shouldPrepare) {
            if (query.hasJoining()) {
                query.getConcreteSubclassJoinedMappingIndexes().put(query.getReferenceClass(), query.getJoinedAttributeManager().getJoinedMappingIndexes_());
            }
            query.getConcreteSubclassCalls().put(query.getReferenceClass(), (DatabaseCall) this.call);
            query.setTranslationRow(translationRow);
        }
    } else {
        setCall(call);
        if (shouldPrepare && query.hasJoining()) {
            query.getJoinedAttributeManager().setJoinedMappingIndexes_(query.getConcreteSubclassJoinedMappingIndexes().get(query.getReferenceClass()));
        }
    }
    return super.selectOneRow();
}
Also used : ObjectLevelReadQuery(org.eclipse.persistence.queries.ObjectLevelReadQuery) DatabaseCall(org.eclipse.persistence.internal.databaseaccess.DatabaseCall) AbstractRecord(org.eclipse.persistence.internal.sessions.AbstractRecord)

Aggregations

DatabaseCall (org.eclipse.persistence.internal.databaseaccess.DatabaseCall)31 DatabasePlatform (org.eclipse.persistence.internal.databaseaccess.DatabasePlatform)11 EntityManager (jakarta.persistence.EntityManager)9 DatabaseException (org.eclipse.persistence.exceptions.DatabaseException)9 EntityManagerFactoryImpl (org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl)8 GenericEntity (org.eclipse.persistence.jpa.test.property.model.GenericEntity)8 Test (org.junit.Test)8 SQLCall (org.eclipse.persistence.queries.SQLCall)6 StoredProcedureCall (org.eclipse.persistence.queries.StoredProcedureCall)6 PersistenceException (jakarta.persistence.PersistenceException)5 Platform (org.eclipse.persistence.internal.databaseaccess.Platform)5 AbstractRecord (org.eclipse.persistence.internal.sessions.AbstractRecord)5 ResultSet (java.sql.ResultSet)4 SQLException (java.sql.SQLException)4 DatabaseAccessor (org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor)4 DatasourceCallQueryMechanism (org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism)4 AbstractSession (org.eclipse.persistence.internal.sessions.AbstractSession)4 ResultSetMetaData (java.sql.ResultSetMetaData)3 Statement (java.sql.Statement)3 UnitOfWorkImpl (org.eclipse.persistence.internal.sessions.UnitOfWorkImpl)3