Search in sources :

Example 1 with JdbcParameterBinder

use of org.hibernate.sql.exec.spi.JdbcParameterBinder in project hibernate-orm by hibernate.

the class NativeNonSelectQueryPlanImpl method executeUpdate.

@Override
public int executeUpdate(DomainQueryExecutionContext executionContext) {
    executionContext.getSession().autoFlushIfRequired(affectedTableNames);
    BulkOperationCleanupAction.schedule(executionContext.getSession(), affectedTableNames);
    final List<JdbcParameterBinder> jdbcParameterBinders;
    final JdbcParameterBindings jdbcParameterBindings;
    final QueryParameterBindings queryParameterBindings = executionContext.getQueryParameterBindings();
    if (parameterList == null || parameterList.isEmpty()) {
        jdbcParameterBinders = Collections.emptyList();
        jdbcParameterBindings = JdbcParameterBindings.NO_BINDINGS;
    } else {
        jdbcParameterBinders = new ArrayList<>(parameterList.size());
        jdbcParameterBindings = new JdbcParameterBindingsImpl(parameterList.size());
        jdbcParameterBindings.registerNativeQueryParameters(queryParameterBindings, parameterList, jdbcParameterBinders, executionContext.getSession().getFactory());
    }
    final JdbcMutation jdbcMutation = new NativeJdbcMutation(sql, jdbcParameterBinders, affectedTableNames);
    final JdbcMutationExecutor executor = StandardJdbcMutationExecutor.INSTANCE;
    final SharedSessionContractImplementor session = executionContext.getSession();
    // return jdbcServices.getJdbcMutationExecutor().execute(
    return executor.execute(jdbcMutation, jdbcParameterBindings, sql -> session.getJdbcCoordinator().getStatementPreparer().prepareStatement(sql), (integer, preparedStatement) -> {
    }, SqmJdbcExecutionContextAdapter.usingLockingAndPaging(executionContext));
}
Also used : NativeJdbcMutation(org.hibernate.sql.exec.spi.NativeJdbcMutation) NativeJdbcMutation(org.hibernate.sql.exec.spi.NativeJdbcMutation) JdbcMutation(org.hibernate.sql.exec.spi.JdbcMutation) JdbcParameterBindingsImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) QueryParameterBindings(org.hibernate.query.spi.QueryParameterBindings) JdbcParameterBinder(org.hibernate.sql.exec.spi.JdbcParameterBinder) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings) JdbcMutationExecutor(org.hibernate.sql.exec.spi.JdbcMutationExecutor) StandardJdbcMutationExecutor(org.hibernate.sql.exec.internal.StandardJdbcMutationExecutor)

Example 2 with JdbcParameterBinder

use of org.hibernate.sql.exec.spi.JdbcParameterBinder in project hibernate-orm by hibernate.

the class DeferredResultSetAccess method executeQuery.

private void executeQuery() {
    final LogicalConnectionImplementor logicalConnection = getPersistenceContext().getJdbcCoordinator().getLogicalConnection();
    final QueryOptions queryOptions = executionContext.getQueryOptions();
    try {
        LOG.tracef("Executing query to retrieve ResultSet : %s", finalSql);
        // prepare the query
        preparedStatement = statementCreator.apply(finalSql);
        // set options
        if (queryOptions != null) {
            if (queryOptions.getFetchSize() != null) {
                preparedStatement.setFetchSize(queryOptions.getFetchSize());
            }
            if (queryOptions.getTimeout() != null) {
                preparedStatement.setQueryTimeout(queryOptions.getTimeout());
            }
        }
        // bind parameters
        // todo : validate that all query parameters were bound?
        int paramBindingPosition = 1;
        paramBindingPosition += limitHandler.bindLimitParametersAtStartOfQuery(limit, preparedStatement, paramBindingPosition);
        for (JdbcParameterBinder parameterBinder : jdbcSelect.getParameterBinders()) {
            parameterBinder.bindParameterValue(preparedStatement, paramBindingPosition++, jdbcParameterBindings, executionContext);
        }
        paramBindingPosition += limitHandler.bindLimitParametersAtEndOfQuery(limit, preparedStatement, paramBindingPosition);
        if (!jdbcSelect.usesLimitParameters() && limit != null && limit.getMaxRows() != null) {
            limitHandler.setMaxRows(limit, preparedStatement);
        } else {
            final int maxRows = jdbcSelect.getMaxRows();
            if (maxRows != Integer.MAX_VALUE) {
                preparedStatement.setMaxRows(maxRows);
            }
        }
        final SessionEventListenerManager eventListenerManager = executionContext.getSession().getEventListenerManager();
        long executeStartNanos = 0;
        if (this.sqlStatementLogger.getLogSlowQuery() > 0) {
            executeStartNanos = System.nanoTime();
        }
        try {
            eventListenerManager.jdbcExecuteStatementStart();
            resultSet = wrapResultSet(preparedStatement.executeQuery());
        } finally {
            eventListenerManager.jdbcExecuteStatementEnd();
            sqlStatementLogger.logSlowQuery(preparedStatement, executeStartNanos);
        }
        // For dialects that don't support an offset clause
        final int rowsToSkip;
        if (!jdbcSelect.usesLimitParameters() && limit != null && limit.getFirstRow() != null && !limitHandler.supportsLimitOffset()) {
            rowsToSkip = limit.getFirstRow();
        } else {
            rowsToSkip = jdbcSelect.getRowsToSkip();
        }
        if (rowsToSkip != 0) {
            try {
                resultSet.absolute(rowsToSkip);
            } catch (SQLException ex) {
                // To avoid throwing a wrong exception in case this was some other error, check if we can advance to next
                try {
                    resultSet.next();
                } catch (SQLException ex2) {
                    throw ex;
                }
                // Traverse to the actual row
                for (int i = 1; i < rowsToSkip && resultSet.next(); i++) {
                }
            }
        }
        logicalConnection.getResourceRegistry().register(resultSet, preparedStatement);
    } catch (SQLException e) {
        throw executionContext.getSession().getJdbcServices().getSqlExceptionHelper().convert(e, "JDBC exception executing SQL [" + finalSql + "]");
    } finally {
        logicalConnection.afterStatement();
    }
}
Also used : SQLException(java.sql.SQLException) LogicalConnectionImplementor(org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor) JdbcParameterBinder(org.hibernate.sql.exec.spi.JdbcParameterBinder) QueryOptions(org.hibernate.query.spi.QueryOptions) SessionEventListenerManager(org.hibernate.engine.spi.SessionEventListenerManager)

Example 3 with JdbcParameterBinder

use of org.hibernate.sql.exec.spi.JdbcParameterBinder in project hibernate-orm by hibernate.

the class StandardJdbcMutationExecutor method execute.

@Override
public int execute(JdbcMutation jdbcMutation, JdbcParameterBindings jdbcParameterBindings, Function<String, PreparedStatement> statementCreator, BiConsumer<Integer, PreparedStatement> expectationCheck, ExecutionContext executionContext) {
    final SharedSessionContractImplementor session = executionContext.getSession();
    session.autoFlushIfRequired(jdbcMutation.getAffectedTableNames());
    final LogicalConnectionImplementor logicalConnection = session.getJdbcCoordinator().getLogicalConnection();
    final JdbcServices jdbcServices = session.getJdbcServices();
    final QueryOptions queryOptions = executionContext.getQueryOptions();
    final String finalSql;
    if (queryOptions == null) {
        finalSql = jdbcMutation.getSql();
    } else {
        finalSql = jdbcServices.getDialect().addSqlHintOrComment(jdbcMutation.getSql(), queryOptions, executionContext.getSession().getFactory().getSessionFactoryOptions().isCommentsEnabled());
    }
    try {
        // prepare the query
        final PreparedStatement preparedStatement = statementCreator.apply(finalSql);
        try {
            if (executionContext.getQueryOptions().getTimeout() != null) {
                preparedStatement.setQueryTimeout(executionContext.getQueryOptions().getTimeout());
            }
            // bind parameters
            // todo : validate that all query parameters were bound?
            int paramBindingPosition = 1;
            for (JdbcParameterBinder parameterBinder : jdbcMutation.getParameterBinders()) {
                parameterBinder.bindParameterValue(preparedStatement, paramBindingPosition++, jdbcParameterBindings, executionContext);
            }
            session.getEventListenerManager().jdbcExecuteStatementStart();
            try {
                int rows = preparedStatement.executeUpdate();
                expectationCheck.accept(rows, preparedStatement);
                return rows;
            } finally {
                session.getEventListenerManager().jdbcExecuteStatementEnd();
            }
        } finally {
            logicalConnection.getResourceRegistry().release(preparedStatement);
        }
    } catch (SQLException e) {
        throw jdbcServices.getSqlExceptionHelper().convert(e, "JDBC exception executing SQL [" + finalSql + "]");
    } finally {
        executionContext.afterStatement(logicalConnection);
    }
}
Also used : SQLException(java.sql.SQLException) LogicalConnectionImplementor(org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) PreparedStatement(java.sql.PreparedStatement) JdbcParameterBinder(org.hibernate.sql.exec.spi.JdbcParameterBinder) QueryOptions(org.hibernate.query.spi.QueryOptions)

Example 4 with JdbcParameterBinder

use of org.hibernate.sql.exec.spi.JdbcParameterBinder in project hibernate-orm by hibernate.

the class ProcedureCallImpl method buildOutputs.

private ProcedureOutputsImpl buildOutputs() {
    // todo : going to need a very specialized Loader for this.
    // or, might be a good time to look at splitting Loader up into:
    // 1) building statement objects
    // 2) executing statement objects
    // 3) processing result sets
    // for now assume there are no resultClasses nor mappings defined..
    // TOTAL PROOF-OF-CONCEPT!!!!!!
    // todo : how to identify calls which should be in the form `{? = call procName...}` ??? (note leading param marker)
    // more than likely this will need to be a method on the native API.  I can see this as a trigger to
    // both: (1) add the `? = ` part and also (2) register a REFCURSOR parameter for DBs (Oracle, PGSQL) that
    // need it.
    final CallableStatementSupport callableStatementSupport = getSession().getJdbcServices().getJdbcEnvironment().getDialect().getCallableStatementSupport();
    this.call = callableStatementSupport.interpretCall(this);
    final Map<ProcedureParameter<?>, JdbcCallParameterRegistration> parameterRegistrations = new IdentityHashMap<>();
    final List<JdbcCallRefCursorExtractor> refCursorExtractors = new ArrayList<>();
    if (call.getFunctionReturn() != null) {
        parameterRegistrations.put(functionReturn, call.getFunctionReturn());
        final JdbcCallRefCursorExtractorImpl refCursorExtractor = call.getFunctionReturn().getRefCursorExtractor();
        if (refCursorExtractor != null) {
            refCursorExtractors.add(refCursorExtractor);
        }
    }
    final List<? extends ProcedureParameterImplementor<?>> registrations = getParameterMetadata().getRegistrationsAsList();
    final List<JdbcCallParameterRegistration> jdbcParameters = call.getParameterRegistrations();
    for (int i = 0; i < registrations.size(); i++) {
        final JdbcCallParameterRegistration jdbcCallParameterRegistration = jdbcParameters.get(i);
        parameterRegistrations.put(registrations.get(i), jdbcCallParameterRegistration);
        final JdbcCallRefCursorExtractorImpl refCursorExtractor = jdbcCallParameterRegistration.getRefCursorExtractor();
        if (refCursorExtractor != null) {
            refCursorExtractors.add(refCursorExtractor);
        }
    }
    LOG.debugf("Preparing procedure call : %s", call);
    final CallableStatement statement = (CallableStatement) getSession().getJdbcCoordinator().getStatementPreparer().prepareStatement(call.getSql(), true);
    // Register the parameter mode and type
    callableStatementSupport.registerParameters(procedureName, call, statement, parameterMetadata, getSession());
    // Apply the parameter bindings
    final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(parameterRegistrations.size());
    for (Map.Entry<ProcedureParameter<?>, JdbcCallParameterRegistration> entry : parameterRegistrations.entrySet()) {
        final JdbcCallParameterRegistration registration = entry.getValue();
        if (registration.getParameterBinder() != null) {
            final ProcedureParameter<?> parameter = entry.getKey();
            final QueryParameterBinding<?> binding = getParameterBindings().getBinding(parameter);
            if (!binding.isBound()) {
                if (parameter.getPosition() == null) {
                    throw new IllegalArgumentException("The parameter named [" + parameter + "] was not set! You need to call the setParameter method.");
                } else {
                    throw new IllegalArgumentException("The parameter at position [" + parameter + "] was not set! You need to call the setParameter method.");
                }
            }
            jdbcParameterBindings.addBinding((JdbcParameter) registration.getParameterBinder(), new JdbcParameterBindingImpl((JdbcMapping) registration.getParameterType(), binding.getBindValue()));
        }
    }
    final JdbcCallRefCursorExtractor[] extractors = refCursorExtractors.toArray(new JdbcCallRefCursorExtractor[0]);
    final ExecutionContext executionContext = new ExecutionContext() {

        private final Callback callback = new CallbackImpl();

        @Override
        public SharedSessionContractImplementor getSession() {
            return ProcedureCallImpl.this.getSession();
        }

        @Override
        public QueryOptions getQueryOptions() {
            return new QueryOptionsAdapter() {

                @Override
                public Boolean isReadOnly() {
                    return false;
                }
            };
        }

        @Override
        public String getQueryIdentifier(String sql) {
            return sql;
        }

        @Override
        public QueryParameterBindings getQueryParameterBindings() {
            return QueryParameterBindings.NO_PARAM_BINDINGS;
        }

        @Override
        public Callback getCallback() {
            return callback;
        }
    };
    try {
        int paramBindingPosition = call.getFunctionReturn() == null ? 1 : 2;
        for (JdbcParameterBinder parameterBinder : call.getParameterBinders()) {
            parameterBinder.bindParameterValue(statement, paramBindingPosition, jdbcParameterBindings, executionContext);
            paramBindingPosition++;
        }
    } catch (SQLException e) {
        throw getSession().getJdbcServices().getSqlExceptionHelper().convert(e, "Error registering CallableStatement parameters", procedureName);
    }
    return new ProcedureOutputsImpl(this, parameterRegistrations, extractors, statement);
}
Also used : ProcedureParameter(org.hibernate.query.procedure.ProcedureParameter) JdbcCallRefCursorExtractorImpl(org.hibernate.sql.exec.internal.JdbcCallRefCursorExtractorImpl) CallbackImpl(org.hibernate.sql.exec.internal.CallbackImpl) JdbcMapping(org.hibernate.metamodel.mapping.JdbcMapping) SQLException(java.sql.SQLException) IdentityHashMap(java.util.IdentityHashMap) ArrayList(java.util.ArrayList) JdbcCallRefCursorExtractor(org.hibernate.sql.exec.spi.JdbcCallRefCursorExtractor) CallableStatement(java.sql.CallableStatement) JdbcParameterBinder(org.hibernate.sql.exec.spi.JdbcParameterBinder) JdbcParameterBindingsImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl) JdbcParameterBindingImpl(org.hibernate.sql.exec.internal.JdbcParameterBindingImpl) CallableStatementSupport(org.hibernate.procedure.spi.CallableStatementSupport) ExecutionContext(org.hibernate.sql.exec.spi.ExecutionContext) Callback(org.hibernate.sql.exec.spi.Callback) JdbcCallParameterRegistration(org.hibernate.sql.exec.spi.JdbcCallParameterRegistration) QueryOptionsAdapter(org.hibernate.query.spi.QueryOptionsAdapter) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) JdbcParameterBindings(org.hibernate.sql.exec.spi.JdbcParameterBindings)

Example 5 with JdbcParameterBinder

use of org.hibernate.sql.exec.spi.JdbcParameterBinder in project hibernate-orm by hibernate.

the class ProcedureParameterImpl method toJdbcParameterRegistration.

@Override
public JdbcCallParameterRegistration toJdbcParameterRegistration(int startIndex, ProcedureCallImplementor<?> procedureCall) {
    final QueryParameterBinding<T> binding = procedureCall.getParameterBindings().getBinding(this);
    final BindableType<T> typeToUse = BindingTypeHelper.INSTANCE.resolveTemporalPrecision(binding == null || binding.getExplicitTemporalPrecision() == null ? null : binding.getExplicitTemporalPrecision(), getHibernateType(), procedureCall.getSession().getFactory());
    final String name;
    if (procedureCall.getParameterStrategy() == ParameterStrategy.NAMED && canDoNameParameterBinding(typeToUse, procedureCall)) {
        name = this.name;
    } else {
        name = null;
    }
    final JdbcParameterBinder parameterBinder;
    final JdbcCallRefCursorExtractorImpl refCursorExtractor;
    final JdbcCallParameterExtractorImpl<T> parameterExtractor;
    switch(mode) {
        case REF_CURSOR:
            refCursorExtractor = new JdbcCallRefCursorExtractorImpl(name, startIndex);
            parameterBinder = null;
            parameterExtractor = null;
            break;
        case IN:
            parameterBinder = getParameterBinder(typeToUse, name);
            parameterExtractor = null;
            refCursorExtractor = null;
            break;
        case INOUT:
            parameterBinder = getParameterBinder(typeToUse, name);
            parameterExtractor = new JdbcCallParameterExtractorImpl<>(procedureCall.getProcedureName(), name, startIndex, typeToUse);
            refCursorExtractor = null;
            break;
        default:
            parameterBinder = null;
            parameterExtractor = new JdbcCallParameterExtractorImpl<>(procedureCall.getProcedureName(), name, startIndex, typeToUse);
            refCursorExtractor = null;
            break;
    }
    return new JdbcCallParameterRegistrationImpl(name, startIndex, mode, typeToUse, parameterBinder, parameterExtractor, refCursorExtractor);
}
Also used : JdbcCallRefCursorExtractorImpl(org.hibernate.sql.exec.internal.JdbcCallRefCursorExtractorImpl) JdbcCallParameterRegistrationImpl(org.hibernate.sql.exec.internal.JdbcCallParameterRegistrationImpl) JdbcParameterBinder(org.hibernate.sql.exec.spi.JdbcParameterBinder)

Aggregations

JdbcParameterBinder (org.hibernate.sql.exec.spi.JdbcParameterBinder)7 JdbcParameterBindingsImpl (org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl)4 JdbcParameterBindings (org.hibernate.sql.exec.spi.JdbcParameterBindings)4 SQLException (java.sql.SQLException)3 QueryParameterBindings (org.hibernate.query.spi.QueryParameterBindings)3 SharedSessionContractImplementor (org.hibernate.engine.spi.SharedSessionContractImplementor)2 QueryOptions (org.hibernate.query.spi.QueryOptions)2 LogicalConnectionImplementor (org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor)2 JdbcCallRefCursorExtractorImpl (org.hibernate.sql.exec.internal.JdbcCallRefCursorExtractorImpl)2 JdbcSelect (org.hibernate.sql.exec.spi.JdbcSelect)2 JdbcSelectExecutor (org.hibernate.sql.exec.spi.JdbcSelectExecutor)2 CallableStatement (java.sql.CallableStatement)1 PreparedStatement (java.sql.PreparedStatement)1 ArrayList (java.util.ArrayList)1 IdentityHashMap (java.util.IdentityHashMap)1 Map (java.util.Map)1 JdbcServices (org.hibernate.engine.jdbc.spi.JdbcServices)1 SessionEventListenerManager (org.hibernate.engine.spi.SessionEventListenerManager)1 JdbcMapping (org.hibernate.metamodel.mapping.JdbcMapping)1 CallableStatementSupport (org.hibernate.procedure.spi.CallableStatementSupport)1