use of org.hibernate.sql.exec.internal.CallbackImpl in project hibernate-orm by hibernate.
the class SingleIdLoadPlan method load.
public T load(Object restrictedValue, Object entityInstance, Boolean readOnly, Boolean singleResultExpected, SharedSessionContractImplementor session) {
final int jdbcTypeCount = restrictivePart.getJdbcTypeCount();
assert jdbcParameters.size() % jdbcTypeCount == 0;
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(jdbcTypeCount);
jdbcSelect.bindFilterJdbcParameters(jdbcParameterBindings);
int offset = 0;
while (offset < jdbcParameters.size()) {
offset += jdbcParameterBindings.registerParametersForEachJdbcValue(restrictedValue, Clause.WHERE, offset, restrictivePart, jdbcParameters, session);
}
assert offset == jdbcParameters.size();
final QueryOptions queryOptions = new SimpleQueryOptions(lockOptions, readOnly);
final Callback callback = new CallbackImpl();
final List<T> list = JdbcSelectExecutorStandardImpl.INSTANCE.list(jdbcSelect, jdbcParameterBindings, new ExecutionContext() {
@Override
public SharedSessionContractImplementor getSession() {
return session;
}
@Override
public Object getEntityInstance() {
return entityInstance;
}
@Override
public Object getEntityId() {
return restrictedValue;
}
@Override
public QueryOptions getQueryOptions() {
return queryOptions;
}
@Override
public String getQueryIdentifier(String sql) {
return sql;
}
@Override
public QueryParameterBindings getQueryParameterBindings() {
return QueryParameterBindings.NO_PARAM_BINDINGS;
}
@Override
public Callback getCallback() {
return callback;
}
}, getRowTransformer(), singleResultExpected ? ListResultsConsumer.UniqueSemantic.ASSERT : ListResultsConsumer.UniqueSemantic.FILTER);
if (list.isEmpty()) {
return null;
}
final T entity = list.get(0);
if (persister != null) {
callback.invokeAfterLoadActions(session, entity, persister);
}
return entity;
}
use of org.hibernate.sql.exec.internal.CallbackImpl 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.CallbackImpl in project hibernate-orm by hibernate.
the class AbstractNaturalIdLoader method selectByNaturalId.
/**
* Perform a select, restricted by natural-id, based on `domainResultProducer` and `fetchProcessor`
*/
protected <L> L selectByNaturalId(Object bindValue, NaturalIdLoadOptions options, BiFunction<TableGroup, LoaderSqlAstCreationState, DomainResult<?>> domainResultProducer, LoaderSqlAstCreationState.FetchProcessor fetchProcessor, Function<Boolean, Long> statementStartHandler, BiConsumer<Object, Long> statementCompletionHandler, SharedSessionContractImplementor session) {
final SessionFactoryImplementor sessionFactory = session.getFactory();
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
final LockOptions lockOptions;
if (options.getLockOptions() != null) {
lockOptions = options.getLockOptions();
} else {
lockOptions = LockOptions.NONE;
}
final NavigablePath entityPath = new NavigablePath(entityDescriptor.getRootPathName());
final QuerySpec rootQuerySpec = new QuerySpec(true);
final LoaderSqlAstCreationState sqlAstCreationState = new LoaderSqlAstCreationState(rootQuerySpec, new SqlAliasBaseManager(), new SimpleFromClauseAccessImpl(), lockOptions, fetchProcessor, true, sessionFactory);
final TableGroup rootTableGroup = entityDescriptor.createRootTableGroup(true, entityPath, null, () -> rootQuerySpec::applyPredicate, sqlAstCreationState, sessionFactory);
rootQuerySpec.getFromClause().addRoot(rootTableGroup);
sqlAstCreationState.getFromClauseAccess().registerTableGroup(entityPath, rootTableGroup);
final DomainResult<?> domainResult = domainResultProducer.apply(rootTableGroup, sqlAstCreationState);
final SelectStatement sqlSelect = new SelectStatement(rootQuerySpec, Collections.singletonList(domainResult));
final List<JdbcParameter> jdbcParameters = new ArrayList<>(naturalIdMapping.getJdbcTypeCount());
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl(jdbcParameters.size());
applyNaturalIdRestriction(bindValue, rootTableGroup, rootQuerySpec::applyPredicate, (jdbcParameter, jdbcParameterBinding) -> {
jdbcParameters.add(jdbcParameter);
jdbcParamBindings.addBinding(jdbcParameter, jdbcParameterBinding);
}, sqlAstCreationState, session);
final QueryOptions queryOptions = new SimpleQueryOptions(lockOptions, false);
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator(sessionFactory, sqlSelect).translate(jdbcParamBindings, queryOptions);
final StatisticsImplementor statistics = sessionFactory.getStatistics();
final Long startToken = statementStartHandler.apply(statistics.isStatisticsEnabled());
// noinspection unchecked
final List<L> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(jdbcSelect, jdbcParamBindings, new ExecutionContext() {
private final Callback callback = new CallbackImpl();
@Override
public SharedSessionContractImplementor getSession() {
return session;
}
@Override
public QueryOptions getQueryOptions() {
return queryOptions;
}
@Override
public String getQueryIdentifier(String sql) {
return sql;
}
@Override
public QueryParameterBindings getQueryParameterBindings() {
return QueryParameterBindings.NO_PARAM_BINDINGS;
}
@Override
public Callback getCallback() {
return callback;
}
}, row -> (L) row[0], ListResultsConsumer.UniqueSemantic.FILTER);
if (results.size() > 1) {
throw new HibernateException(String.format("Loading by natural-id returned more that one row : %s", entityDescriptor.getEntityName()));
}
final L result;
if (results.isEmpty()) {
result = null;
} else {
result = results.get(0);
}
statementCompletionHandler.accept(result, startToken);
return result;
}
use of org.hibernate.sql.exec.internal.CallbackImpl in project hibernate-orm by hibernate.
the class SingleUniqueKeyEntityLoaderStandard method load.
@Override
public T load(Object ukValue, LockOptions lockOptions, Boolean readOnly, SharedSessionContractImplementor session) {
final SessionFactoryImplementor sessionFactory = session.getFactory();
// todo (6.0) : cache the SQL AST and JdbcParameters
final List<JdbcParameter> jdbcParameters = new ArrayList<>();
final SelectStatement sqlAst = LoaderSelectBuilder.createSelectByUniqueKey(entityDescriptor, Collections.emptyList(), uniqueKeyAttribute, null, 1, LoadQueryInfluencers.NONE, LockOptions.NONE, jdbcParameters::add, sessionFactory);
final JdbcServices jdbcServices = sessionFactory.getJdbcServices();
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory();
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(jdbcParameters.size());
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(ukValue, Clause.WHERE, uniqueKeyAttribute, jdbcParameters, session);
assert offset == jdbcParameters.size();
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator(sessionFactory, sqlAst).translate(jdbcParameterBindings, QueryOptions.NONE);
final List<Object> list = sessionFactory.getJdbcServices().getJdbcSelectExecutor().list(jdbcSelect, jdbcParameterBindings, new ExecutionContext() {
private final Callback callback = new CallbackImpl();
@Override
public SharedSessionContractImplementor getSession() {
return session;
}
@Override
public QueryOptions getQueryOptions() {
return new QueryOptionsAdapter() {
@Override
public Boolean isReadOnly() {
return readOnly;
}
};
}
@Override
public String getQueryIdentifier(String sql) {
return sql;
}
@Override
public QueryParameterBindings getQueryParameterBindings() {
return QueryParameterBindings.NO_PARAM_BINDINGS;
}
@Override
public Callback getCallback() {
return callback;
}
}, row -> row[0], ListResultsConsumer.UniqueSemantic.FILTER);
switch(list.size()) {
case 0:
return null;
case 1:
// noinspection unchecked
return (T) list.get(0);
}
throw new HibernateException("More than one row with the given identifier was found: " + ukValue + ", for class: " + entityDescriptor.getEntityName());
}
use of org.hibernate.sql.exec.internal.CallbackImpl in project hibernate-orm by hibernate.
the class OutputsImpl method extractResults.
protected List extractResults(ResultSet resultSet) {
final DirectResultSetAccess resultSetAccess = new DirectResultSetAccess(context.getSession(), jdbcStatement, resultSet);
final ProcedureCallImpl procedureCall = (ProcedureCallImpl) context;
final ResultSetMapping resultSetMapping = procedureCall.getResultSetMapping();
final JavaTypeRegistry javaTypeRegistry = context.getSession().getTypeConfiguration().getJavaTypeRegistry();
procedureCall.getParameterBindings().visitBindings((parameterImplementor, queryParameterBinding) -> {
ProcedureParameter parameter = (ProcedureParameter) parameterImplementor;
if (parameter.getMode() == ParameterMode.INOUT) {
final JavaType<?> basicType = javaTypeRegistry.getDescriptor(parameterImplementor.getParameterType());
if (basicType != null) {
resultSetMapping.addResultBuilder(new ScalarDomainResultBuilder<>(basicType));
} else {
throw new NotYetImplementedFor6Exception(getClass());
}
}
});
final ExecutionContext executionContext = new ExecutionContext() {
private final Callback callback = new CallbackImpl();
@Override
public SharedSessionContractImplementor getSession() {
return OutputsImpl.this.context.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;
}
};
final JdbcValues jdbcValues = new JdbcValuesResultSetImpl(resultSetAccess, null, null, this.context.getQueryOptions(), resultSetMapping.resolve(resultSetAccess, getSessionFactory()), null, executionContext);
final RowReader<Object[]> rowReader = (RowReader<Object[]>) ResultsHelper.createRowReader(executionContext, null, RowTransformerPassThruImpl.INSTANCE, jdbcValues);
/*
* Processing options effectively are only used for entity loading. Here we don't need these values.
*/
final JdbcValuesSourceProcessingOptions processingOptions = new JdbcValuesSourceProcessingOptions() {
@Override
public Object getEffectiveOptionalObject() {
return null;
}
@Override
public String getEffectiveOptionalEntityName() {
return null;
}
@Override
public Serializable getEffectiveOptionalId() {
return null;
}
@Override
public boolean shouldReturnProxies() {
return true;
}
};
final JdbcValuesSourceProcessingStateStandardImpl jdbcValuesSourceProcessingState = new JdbcValuesSourceProcessingStateStandardImpl(executionContext, processingOptions, executionContext::registerLoadingEntityEntry);
try {
final RowProcessingStateStandardImpl rowProcessingState = new RowProcessingStateStandardImpl(jdbcValuesSourceProcessingState, executionContext, rowReader, jdbcValues);
final List results = new ArrayList<>();
while (rowProcessingState.next()) {
results.add(rowReader.readRow(rowProcessingState, processingOptions));
rowProcessingState.finishRowProcessing();
}
return results;
} finally // catch (SQLException e) {
// throw context.getSession().getExceptionConverter().convert( e, "Error processing return rows" );
// }
{
rowReader.finishUp(jdbcValuesSourceProcessingState);
jdbcValuesSourceProcessingState.finishUp();
jdbcValues.finishUp(this.context.getSession());
}
}
Aggregations