Search in sources :

Example 1 with QueryParameter

use of org.hibernate.query.QueryParameter in project hibernate-orm by hibernate.

the class QueryParameterBindingsImpl method verifyParametersBound.

public void verifyParametersBound(boolean reserveFirstParameter) {
    // verify named parameters bound
    for (Map.Entry<QueryParameter, QueryParameterBinding> bindEntry : parameterBindingMap.entrySet()) {
        if (!bindEntry.getValue().isBound()) {
            if (bindEntry.getKey().getName() != null) {
                throw new QueryException("Named parameter [" + bindEntry.getKey().getName() + "] not set");
            } else {
                throw new QueryException("Parameter memento [" + bindEntry.getKey() + "] not set");
            }
        }
    }
    // verify position parameters bound
    int startIndex = 0;
    if (!parameterMetadata.isOrdinalParametersZeroBased()) {
        startIndex = 1;
    }
    for (int i = startIndex; i < positionalParameterBindings.size(); i++) {
        QueryParameterBinding binding = null;
        if (parameterMetadata.isOrdinalParametersZeroBased()) {
            binding = positionalParameterBindings.get(i);
        } else {
            binding = positionalParameterBindings.get(i - 1);
        }
        if (binding == null || !binding.isBound()) {
            throw new QueryException("Positional parameter [" + i + "] not set");
        }
    }
    // verify position parameter count is correct
    final int positionalValueSpan = calculatePositionalValueSpan(reserveFirstParameter);
    final int positionCounts = parameterMetadata.getPositionalParameterCount();
    if (positionCounts != positionalValueSpan) {
        if (reserveFirstParameter && positionCounts - 1 != positionalValueSpan) {
            throw new QueryException("Expected positional parameter count: " + (positionCounts - 1) + ", actually detected " + positionalValueSpan);
        } else if (!reserveFirstParameter) {
            throw new QueryException("Expected positional parameter count: " + (positionCounts) + ", actually detected " + positionalValueSpan);
        }
    }
}
Also used : QueryParameter(org.hibernate.query.QueryParameter) QueryException(org.hibernate.QueryException) QueryParameterBinding(org.hibernate.query.spi.QueryParameterBinding) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap)

Example 2 with QueryParameter

use of org.hibernate.query.QueryParameter in project hibernate-orm by hibernate.

the class QueryParameterBindingsImpl method expandListValuedParameters.

/**
 * @deprecated (since 5.2) expected changes to "collection-valued parameter binding" in 6.0
 */
@Deprecated
@SuppressWarnings("unchecked")
public String expandListValuedParameters(String queryString, SharedSessionContractImplementor session) {
    if (queryString == null) {
        return null;
    }
    if (parameterListBindingMap == null || parameterListBindingMap.isEmpty()) {
        return queryString;
    }
    // more-or-less... for each entry in parameterListBindingMap we will create an
    // entry in parameterBindingMap for each of the values in the bound value list.  afterwards
    // we will clear the parameterListBindingMap.
    // 
    // NOTE that this is essentially the legacy logical prior to modeling QueryParameterBinding/QueryParameterListBinding.
    // Fully expect the details of how this is handled in 6.0
    // HHH-1123
    // Some DBs limit number of IN expressions.  For now, warn...
    final Dialect dialect = session.getFactory().getServiceRegistry().getService(JdbcServices.class).getJdbcEnvironment().getDialect();
    final int inExprLimit = dialect.getInExpressionCountLimit();
    int maxOrdinalPosition = getMaxOrdinalPosition();
    for (Map.Entry<QueryParameter, QueryParameterListBinding> entry : parameterListBindingMap.entrySet()) {
        final QueryParameter sourceParam = entry.getKey();
        final Collection bindValues = entry.getValue().getBindValues();
        if (inExprLimit > 0 && bindValues.size() > inExprLimit) {
            log.tooManyInExpressions(dialect.getClass().getName(), inExprLimit, sourceParam.getName(), bindValues.size());
        }
        final String sourceToken;
        if (sourceParam instanceof NamedParameterDescriptor) {
            sourceToken = ":" + NamedParameterDescriptor.class.cast(sourceParam).getName();
        } else {
            sourceToken = "?" + OrdinalParameterDescriptor.class.cast(sourceParam).getPosition();
        }
        final int loc = StringHelper.indexOfIdentifierWord(queryString, sourceToken);
        if (loc < 0) {
            continue;
        }
        final String beforePlaceholder = queryString.substring(0, loc);
        final String afterPlaceholder = queryString.substring(loc + sourceToken.length());
        // check if placeholder is already immediately enclosed in parentheses
        // (ignoring whitespace)
        boolean isEnclosedInParens = StringHelper.getLastNonWhitespaceCharacter(beforePlaceholder) == '(' && StringHelper.getFirstNonWhitespaceCharacter(afterPlaceholder) == ')';
        if (bindValues.size() == 1 && isEnclosedInParens) {
            // short-circuit for performance when only 1 value and the
            // placeholder is already enclosed in parentheses...
            final QueryParameterBinding syntheticBinding = makeBinding(entry.getValue().getBindType());
            syntheticBinding.setBindValue(bindValues.iterator().next());
            parameterBindingMap.put(sourceParam, syntheticBinding);
            continue;
        }
        StringBuilder expansionList = new StringBuilder();
        int i = 0;
        for (Object bindValue : entry.getValue().getBindValues()) {
            if (i > 0) {
                expansionList.append(", ");
            }
            final QueryParameter syntheticParam;
            if (sourceParam instanceof NamedParameterDescriptor) {
                // in the case of a named parameter, for each value in the bound list-of-values we:
                // 1) create a synthetic named parameter
                // 2) expand the queryString to include each synthetic named param in place of the original
                // 3) create a new synthetic binding for just that single value under the synthetic name
                final String syntheticName = NamedParameterDescriptor.class.cast(sourceParam).getName() + '_' + i;
                expansionList.append(":").append(syntheticName);
                syntheticParam = new NamedParameterDescriptor(syntheticName, sourceParam.getType(), sourceParam.getSourceLocations());
            } else {
                // for the first item, we reuse the original parameter to avoid gaps in the positions
                if (i == 0) {
                    syntheticParam = sourceParam;
                } else {
                    int syntheticPosition = ++maxOrdinalPosition;
                    syntheticParam = new OrdinalParameterDescriptor(syntheticPosition, syntheticPosition - jdbcStyleOrdinalCountBase, sourceParam.getType(), sourceParam.getSourceLocations());
                }
                expansionList.append("?").append(syntheticParam.getPosition());
            }
            final QueryParameterBinding syntheticBinding = makeBinding(entry.getValue().getBindType());
            syntheticBinding.setBindValue(bindValue);
            parameterBindingMap.put(syntheticParam, syntheticBinding);
            i++;
        }
        queryString = StringHelper.replace(beforePlaceholder, afterPlaceholder, sourceToken, expansionList.toString(), true, true);
    }
    if (parameterListBindingMap != null) {
        parameterListBindingMap.clear();
    }
    return queryString;
}
Also used : QueryParameter(org.hibernate.query.QueryParameter) QueryParameterBinding(org.hibernate.query.spi.QueryParameterBinding) QueryParameterListBinding(org.hibernate.query.spi.QueryParameterListBinding) OrdinalParameterDescriptor(org.hibernate.engine.query.spi.OrdinalParameterDescriptor) Dialect(org.hibernate.dialect.Dialect) Collection(java.util.Collection) NamedParameterDescriptor(org.hibernate.engine.query.spi.NamedParameterDescriptor) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap)

Example 3 with QueryParameter

use of org.hibernate.query.QueryParameter 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 String call = getProducer().getJdbcServices().getJdbcEnvironment().getDialect().getCallableStatementSupport().renderCallableStatement(procedureName, getParameterMetadata(), paramBindings, getProducer());
    LOG.debugf("Preparing procedure call : %s", call);
    final CallableStatement statement = (CallableStatement) getSession().getJdbcCoordinator().getStatementPreparer().prepareStatement(call, true);
    // prepare parameters
    getParameterMetadata().visitRegistrations(new Consumer<QueryParameter>() {

        int i = 1;

        @Override
        public void accept(QueryParameter queryParameter) {
            try {
                final ParameterRegistrationImplementor registration = (ParameterRegistrationImplementor) queryParameter;
                registration.prepare(statement, i);
                if (registration.getMode() == ParameterMode.REF_CURSOR) {
                    i++;
                } else {
                    i += registration.getSqlTypes().length;
                }
            } catch (SQLException e) {
                throw getSession().getJdbcServices().getSqlExceptionHelper().convert(e, "Error preparing registered callable parameter", getProcedureName());
            }
        }
    });
    return new ProcedureOutputsImpl(this, statement);
}
Also used : QueryParameter(org.hibernate.query.QueryParameter) SQLException(java.sql.SQLException) CallableStatement(java.sql.CallableStatement) ParameterRegistrationImplementor(org.hibernate.procedure.spi.ParameterRegistrationImplementor)

Example 4 with QueryParameter

use of org.hibernate.query.QueryParameter in project hibernate-orm by hibernate.

the class QueryParameterBindingsImpl method collectNamedParameterBindings.

/**
 * @deprecated (since 5.2) expect a different approach to org.hibernate.engine.spi.QueryParameters in 6.0
 */
@Deprecated
public Map<String, TypedValue> collectNamedParameterBindings() {
    final Map<String, TypedValue> collectedBindings = new HashMap<>();
    for (Map.Entry<QueryParameter, QueryParameterBinding> entry : parameterBindingMap.entrySet()) {
        final String key;
        if (entry.getKey().getPosition() != null) {
            key = Integer.toString(entry.getKey().getPosition());
        } else {
            key = entry.getKey().getName();
        }
        Type bindType = entry.getValue().getBindType();
        if (bindType == null) {
            log.debugf("Binding for parameter [%s] did not define type", key);
            bindType = SerializableType.INSTANCE;
        }
        collectedBindings.put(key, new TypedValue(bindType, entry.getValue().getBindValue()));
    }
    return collectedBindings;
}
Also used : QueryParameter(org.hibernate.query.QueryParameter) SerializableType(org.hibernate.type.SerializableType) Type(org.hibernate.type.Type) QueryParameterBinding(org.hibernate.query.spi.QueryParameterBinding) HashMap(java.util.HashMap) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) TypedValue(org.hibernate.engine.spi.TypedValue)

Aggregations

QueryParameter (org.hibernate.query.QueryParameter)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 TreeMap (java.util.TreeMap)3 QueryParameterBinding (org.hibernate.query.spi.QueryParameterBinding)3 CallableStatement (java.sql.CallableStatement)1 SQLException (java.sql.SQLException)1 Collection (java.util.Collection)1 QueryException (org.hibernate.QueryException)1 Dialect (org.hibernate.dialect.Dialect)1 NamedParameterDescriptor (org.hibernate.engine.query.spi.NamedParameterDescriptor)1 OrdinalParameterDescriptor (org.hibernate.engine.query.spi.OrdinalParameterDescriptor)1 TypedValue (org.hibernate.engine.spi.TypedValue)1 ParameterRegistrationImplementor (org.hibernate.procedure.spi.ParameterRegistrationImplementor)1 QueryParameterListBinding (org.hibernate.query.spi.QueryParameterListBinding)1 SerializableType (org.hibernate.type.SerializableType)1 Type (org.hibernate.type.Type)1