Search in sources :

Example 1 with JdbcValuesResultSetImpl

use of org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl in project hibernate-orm by hibernate.

the class JdbcSelectExecutorStandardImpl method doExecuteQuery.

private <T, R> T doExecuteQuery(JdbcSelect jdbcSelect, JdbcParameterBindings jdbcParameterBindings, ExecutionContext executionContext, RowTransformer<R> rowTransformer, Function<String, PreparedStatement> statementCreator, ResultsConsumer<T, R> resultsConsumer) {
    final DeferredResultSetAccess deferredResultSetAccess = new DeferredResultSetAccess(jdbcSelect, jdbcParameterBindings, executionContext, statementCreator);
    final JdbcValues jdbcValues = resolveJdbcValuesSource(executionContext.getQueryIdentifier(deferredResultSetAccess.getFinalSql()), jdbcSelect, resultsConsumer.canResultsBeCached(), executionContext, deferredResultSetAccess);
    if (rowTransformer == null) {
        @SuppressWarnings("unchecked") final TupleTransformer<R> tupleTransformer = (TupleTransformer<R>) executionContext.getQueryOptions().getTupleTransformer();
        if (tupleTransformer == null) {
            rowTransformer = RowTransformerPassThruImpl.instance();
        } else {
            final List<DomainResult<?>> domainResults = jdbcValues.getValuesMapping().getDomainResults();
            final String[] aliases = new String[domainResults.size()];
            for (int i = 0; i < domainResults.size(); i++) {
                aliases[i] = domainResults.get(i).getResultVariable();
            }
            rowTransformer = new RowTransformerTupleTransformerAdapter<>(aliases, tupleTransformer);
        }
    }
    final boolean stats;
    long startTime = 0;
    final StatisticsImplementor statistics = executionContext.getSession().getFactory().getStatistics();
    if (executionContext.hasQueryExecutionToBeAddedToStatistics() && jdbcValues instanceof JdbcValuesResultSetImpl) {
        stats = statistics.isStatisticsEnabled();
        if (stats) {
            startTime = System.nanoTime();
        }
    } else {
        stats = false;
    }
    /*
		 * 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 executionContext.getEntityInstance();
        }

        @Override
        public String getEffectiveOptionalEntityName() {
            return null;
        }

        @Override
        public Object getEffectiveOptionalId() {
            return executionContext.getEntityId();
        }

        @Override
        public boolean shouldReturnProxies() {
            return true;
        }
    };
    final JdbcValuesSourceProcessingStateStandardImpl valuesProcessingState = new JdbcValuesSourceProcessingStateStandardImpl(executionContext, processingOptions, executionContext::registerLoadingEntityEntry);
    final RowReader<R> rowReader = ResultsHelper.createRowReader(executionContext, // because the EntityEntrys would already have the desired lock mode
    deferredResultSetAccess.usesFollowOnLocking() ? LockOptions.NONE : executionContext.getQueryOptions().getLockOptions(), rowTransformer, jdbcValues);
    final RowProcessingStateStandardImpl rowProcessingState = new RowProcessingStateStandardImpl(valuesProcessingState, executionContext, rowReader, jdbcValues);
    final T result = resultsConsumer.consume(jdbcValues, executionContext.getSession(), processingOptions, valuesProcessingState, rowProcessingState, rowReader);
    if (stats) {
        final long endTime = System.nanoTime();
        final long milliseconds = TimeUnit.MILLISECONDS.convert(endTime - startTime, TimeUnit.NANOSECONDS);
        statistics.queryExecuted(executionContext.getQueryIdentifier(jdbcSelect.getSql()), getResultSize(result), milliseconds);
    }
    return result;
}
Also used : JdbcValuesSourceProcessingOptions(org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions) JdbcValues(org.hibernate.sql.results.jdbc.spi.JdbcValues) DeferredResultSetAccess(org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess) DomainResult(org.hibernate.sql.results.graph.DomainResult) StatisticsImplementor(org.hibernate.stat.spi.StatisticsImplementor) JdbcValuesResultSetImpl(org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl) TupleTransformer(org.hibernate.query.TupleTransformer) JdbcValuesSourceProcessingStateStandardImpl(org.hibernate.sql.results.jdbc.internal.JdbcValuesSourceProcessingStateStandardImpl) RowProcessingStateStandardImpl(org.hibernate.sql.results.internal.RowProcessingStateStandardImpl)

Example 2 with JdbcValuesResultSetImpl

use of org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl in project hibernate-orm by hibernate.

the class JdbcSelectExecutorStandardImpl method resolveJdbcValuesSource.

private JdbcValues resolveJdbcValuesSource(String queryIdentifier, JdbcSelect jdbcSelect, boolean canBeCached, ExecutionContext executionContext, ResultSetAccess resultSetAccess) {
    final SharedSessionContractImplementor session = executionContext.getSession();
    final SessionFactoryImplementor factory = session.getFactory();
    final boolean queryCacheEnabled = factory.getSessionFactoryOptions().isQueryCacheEnabled();
    final List<?> cachedResults;
    final CacheMode cacheMode = JdbcExecHelper.resolveCacheMode(executionContext);
    final JdbcValuesMappingProducer mappingProducer = jdbcSelect.getJdbcValuesMappingProducer();
    final boolean cacheable = queryCacheEnabled && canBeCached && executionContext.getQueryOptions().isResultCachingEnabled() == Boolean.TRUE;
    final QueryKey queryResultsCacheKey;
    if (cacheable && cacheMode.isGetEnabled()) {
        SqlExecLogger.INSTANCE.debugf("Reading Query result cache data per CacheMode#isGetEnabled [%s]", cacheMode.name());
        final Set<String> querySpaces = jdbcSelect.getAffectedTableNames();
        if (querySpaces == null || querySpaces.size() == 0) {
            SqlExecLogger.INSTANCE.tracev("Unexpected querySpaces is {0}", (querySpaces == null ? querySpaces : "empty"));
        } else {
            SqlExecLogger.INSTANCE.tracev("querySpaces is {0}", querySpaces);
        }
        final QueryResultsCache queryCache = factory.getCache().getQueryResultsCache(executionContext.getQueryOptions().getResultCacheRegionName());
        // todo (6.0) : not sure that it is at all important that we account for QueryResults
        // these cached values are "lower level" than that, representing the
        // "raw" JDBC values.
        // 
        // todo (6.0) : relatedly ^^, pretty sure that SqlSelections are also irrelevant
        queryResultsCacheKey = QueryKey.from(jdbcSelect.getSql(), executionContext.getQueryOptions().getLimit(), executionContext.getQueryParameterBindings(), session);
        cachedResults = queryCache.get(// todo (6.0) : QueryCache#get takes the `queryResultsCacheKey` see tat discussion above
        queryResultsCacheKey, // atm we do not even collect querySpaces, but we need to
        querySpaces, session);
        // todo (6.0) : `querySpaces` and `session` are used in QueryCache#get to verify "up-to-dateness" via UpdateTimestampsCache
        // better imo to move UpdateTimestampsCache handling here and have QueryCache be a simple access to
        // the underlying query result cache region.
        // 
        // todo (6.0) : if we go this route (^^), still beneficial to have an abstraction over different UpdateTimestampsCache-based
        // invalidation strategies - QueryCacheInvalidationStrategy
        final StatisticsImplementor statistics = factory.getStatistics();
        if (statistics.isStatisticsEnabled()) {
            if (cachedResults == null) {
                statistics.queryCacheMiss(queryIdentifier, queryCache.getRegion().getName());
            } else {
                statistics.queryCacheHit(queryIdentifier, queryCache.getRegion().getName());
            }
        }
    } else {
        SqlExecLogger.INSTANCE.debugf("Skipping reading Query result cache data: cache-enabled = %s, cache-mode = %s", queryCacheEnabled, cacheMode.name());
        cachedResults = null;
        if (cacheable && cacheMode.isPutEnabled()) {
            queryResultsCacheKey = QueryKey.from(jdbcSelect.getSql(), executionContext.getQueryOptions().getLimit(), executionContext.getQueryParameterBindings(), session);
        } else {
            queryResultsCacheKey = null;
        }
    }
    if (cachedResults == null) {
        final JdbcValuesMetadata metadataForCache;
        final JdbcValuesMapping jdbcValuesMapping;
        if (queryResultsCacheKey == null) {
            jdbcValuesMapping = mappingProducer.resolve(resultSetAccess, factory);
            metadataForCache = null;
        } else {
            // If we need to put the values into the cache, we need to be able to capture the JdbcValuesMetadata
            final CapturingJdbcValuesMetadata capturingMetadata = new CapturingJdbcValuesMetadata(resultSetAccess);
            jdbcValuesMapping = mappingProducer.resolve(capturingMetadata, factory);
            metadataForCache = capturingMetadata.resolveMetadataForCache();
        }
        return new JdbcValuesResultSetImpl(resultSetAccess, queryResultsCacheKey, queryIdentifier, executionContext.getQueryOptions(), jdbcValuesMapping, metadataForCache, executionContext);
    } else {
        final JdbcValuesMapping jdbcValuesMapping;
        if (cachedResults.isEmpty() || !(cachedResults.get(0) instanceof JdbcValuesMetadata)) {
            jdbcValuesMapping = mappingProducer.resolve(resultSetAccess, factory);
        } else {
            jdbcValuesMapping = mappingProducer.resolve((JdbcValuesMetadata) cachedResults.get(0), factory);
        }
        return new JdbcValuesCacheHit(cachedResults, jdbcValuesMapping);
    }
}
Also used : SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) QueryKey(org.hibernate.cache.spi.QueryKey) SharedSessionContractImplementor(org.hibernate.engine.spi.SharedSessionContractImplementor) CacheMode(org.hibernate.CacheMode) StatisticsImplementor(org.hibernate.stat.spi.StatisticsImplementor) QueryResultsCache(org.hibernate.cache.spi.QueryResultsCache) JdbcValuesResultSetImpl(org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl) JdbcValuesMappingProducer(org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer) JdbcValuesMapping(org.hibernate.sql.results.jdbc.spi.JdbcValuesMapping) JdbcValuesMetadata(org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata) JdbcValuesCacheHit(org.hibernate.sql.results.jdbc.internal.JdbcValuesCacheHit)

Example 3 with JdbcValuesResultSetImpl

use of org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl 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());
    }
}
Also used : ProcedureParameter(org.hibernate.query.procedure.ProcedureParameter) RowReader(org.hibernate.sql.results.spi.RowReader) JdbcValuesSourceProcessingOptions(org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions) JdbcValues(org.hibernate.sql.results.jdbc.spi.JdbcValues) CallbackImpl(org.hibernate.sql.exec.internal.CallbackImpl) ArrayList(java.util.ArrayList) JdbcValuesResultSetImpl(org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl) JavaTypeRegistry(org.hibernate.type.descriptor.java.spi.JavaTypeRegistry) ExecutionContext(org.hibernate.sql.exec.spi.ExecutionContext) Callback(org.hibernate.sql.exec.spi.Callback) ResultSetMapping(org.hibernate.query.results.ResultSetMapping) DirectResultSetAccess(org.hibernate.sql.results.jdbc.internal.DirectResultSetAccess) JdbcValuesSourceProcessingStateStandardImpl(org.hibernate.sql.results.jdbc.internal.JdbcValuesSourceProcessingStateStandardImpl) QueryOptionsAdapter(org.hibernate.query.spi.QueryOptionsAdapter) NotYetImplementedFor6Exception(org.hibernate.NotYetImplementedFor6Exception) ArrayList(java.util.ArrayList) List(java.util.List) ProcedureCallImpl(org.hibernate.procedure.internal.ProcedureCallImpl) RowProcessingStateStandardImpl(org.hibernate.sql.results.internal.RowProcessingStateStandardImpl)

Aggregations

JdbcValuesResultSetImpl (org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl)3 RowProcessingStateStandardImpl (org.hibernate.sql.results.internal.RowProcessingStateStandardImpl)2 JdbcValuesSourceProcessingStateStandardImpl (org.hibernate.sql.results.jdbc.internal.JdbcValuesSourceProcessingStateStandardImpl)2 JdbcValues (org.hibernate.sql.results.jdbc.spi.JdbcValues)2 JdbcValuesSourceProcessingOptions (org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions)2 StatisticsImplementor (org.hibernate.stat.spi.StatisticsImplementor)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 CacheMode (org.hibernate.CacheMode)1 NotYetImplementedFor6Exception (org.hibernate.NotYetImplementedFor6Exception)1 QueryKey (org.hibernate.cache.spi.QueryKey)1 QueryResultsCache (org.hibernate.cache.spi.QueryResultsCache)1 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)1 SharedSessionContractImplementor (org.hibernate.engine.spi.SharedSessionContractImplementor)1 ProcedureCallImpl (org.hibernate.procedure.internal.ProcedureCallImpl)1 TupleTransformer (org.hibernate.query.TupleTransformer)1 ProcedureParameter (org.hibernate.query.procedure.ProcedureParameter)1 ResultSetMapping (org.hibernate.query.results.ResultSetMapping)1 QueryOptionsAdapter (org.hibernate.query.spi.QueryOptionsAdapter)1 CallbackImpl (org.hibernate.sql.exec.internal.CallbackImpl)1