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