use of org.hibernate.sql.exec.internal.JdbcCallRefCursorExtractorImpl 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.internal.JdbcCallRefCursorExtractorImpl in project hibernate-orm by hibernate.
the class FunctionReturnImpl method toJdbcFunctionReturn.
@Override
public JdbcCallFunctionReturn toJdbcFunctionReturn(SharedSessionContractImplementor persistenceContext) {
final BindableType<T> ormType;
final JdbcCallRefCursorExtractorImpl refCursorExtractor;
final JdbcCallParameterExtractorImpl<T> parameterExtractor;
if (getJdbcTypeCode() == Types.REF_CURSOR) {
refCursorExtractor = new JdbcCallRefCursorExtractorImpl(null, 1);
ormType = null;
parameterExtractor = null;
} else {
final TypeConfiguration typeConfiguration = persistenceContext.getFactory().getTypeConfiguration();
final JdbcType sqlTypeDescriptor = typeConfiguration.getJdbcTypeRegistry().getDescriptor(getJdbcTypeCode());
final BasicJavaType<?> javaTypeMapping = sqlTypeDescriptor.getJdbcRecommendedJavaTypeMapping(null, null, typeConfiguration);
// noinspection unchecked
ormType = (BindableType<T>) typeConfiguration.standardBasicTypeForJavaType(javaTypeMapping.getJavaTypeClass());
parameterExtractor = new JdbcCallParameterExtractorImpl<>(procedureCall.getProcedureName(), null, 1, ormType);
refCursorExtractor = null;
}
return new JdbcCallFunctionReturnImpl(ormType, parameterExtractor, refCursorExtractor);
}
use of org.hibernate.sql.exec.internal.JdbcCallRefCursorExtractorImpl 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