Example usage for org.hibernate.dialect Dialect getInExpressionCountLimit

List of usage examples for org.hibernate.dialect Dialect getInExpressionCountLimit

Introduction

In this page you can find the example usage for org.hibernate.dialect Dialect getInExpressionCountLimit.

Prototype

public int getInExpressionCountLimit() 

Source Link

Document

Return the limit that the underlying database places on the number of elements in an IN predicate.

Usage

From source file:com.blazebit.persistence.integration.hibernate.Hibernate43Access.java

License:Apache License

private String expandParameterList(SessionImplementor session, ParameterMetadata parameterMetadata,
        String query, String name, TypedValue typedList, Map<String, TypedValue> namedParamsCopy) {
    Collection<?> vals = (Collection<?>) typedList.getValue();

    // HHH-1123//from w  w  w  . j  a  v a  2  s  . c o m
    // Some DBs limit number of IN expressions.  For now, warn...
    final Dialect dialect = session.getFactory().getDialect();
    final int inExprLimit = dialect.getInExpressionCountLimit();
    if (inExprLimit > 0 && vals.size() > inExprLimit) {
        LOG.warning(String.format(
                "Dialect [%s] limits the number of elements in an IN predicate to %s entries.  "
                        + "However, the given parameter list [%s] contained %s entries, which will likely cause failures "
                        + "to execute the query in the database",
                dialect.getClass().getName(), inExprLimit, name, vals.size()));
    }

    Type type = typedList.getType();

    boolean isJpaPositionalParam = parameterMetadata.getNamedParameterDescriptor(name).isJpaStyle();
    String paramPrefix = isJpaPositionalParam ? "?" : ParserHelper.HQL_VARIABLE_PREFIX;
    String placeholder = new StringBuilder(paramPrefix.length() + name.length()).append(paramPrefix)
            .append(name).toString();

    if (query == null) {
        return query;
    }
    int loc = query.indexOf(placeholder);

    if (loc < 0) {
        return query;
    }

    String beforePlaceholder = query.substring(0, loc);
    String afterPlaceholder = query.substring(loc + placeholder.length());

    // check if placeholder is already immediately enclosed in parentheses
    // (ignoring whitespace)
    boolean isEnclosedInParens = StringHelper.getLastNonWhitespaceCharacter(beforePlaceholder) == '('
            && StringHelper.getFirstNonWhitespaceCharacter(afterPlaceholder) == ')';

    if (vals.size() == 1 && isEnclosedInParens) {
        // short-circuit for performance when only 1 value and the
        // placeholder is already enclosed in parentheses...
        namedParamsCopy.put(name, new TypedValue(type, vals.iterator().next()));
        return query;
    }

    StringBuilder list = new StringBuilder(16);
    Iterator<?> iter = vals.iterator();
    int i = 0;
    while (iter.hasNext()) {
        // Variable 'name' can represent a number or contain digit at the end. Surrounding it with
        // characters to avoid ambiguous definition after concatenating value of 'i' counter.
        String alias = (isJpaPositionalParam ? 'x' + name : name) + '_' + i++ + '_';
        if (namedParamsCopy.put(alias, new TypedValue(type, iter.next())) != null) {
            throw new HibernateException(
                    "Repeated usage of alias '" + alias + "' while expanding list parameter.");
        }
        list.append(ParserHelper.HQL_VARIABLE_PREFIX).append(alias);
        if (iter.hasNext()) {
            list.append(", ");
        }
    }
    return StringHelper.replace(beforePlaceholder, afterPlaceholder, placeholder.toString(), list.toString(),
            true, true);
}