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));
}
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();
}
}
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);
}
}
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);
}
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);
}
Aggregations