Skip to content

Instantly share code, notes, and snippets.

@xmedeko
Created October 16, 2012 12:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xmedeko/3899007 to your computer and use it in GitHub Desktop.
Save xmedeko/3899007 to your computer and use it in GitHub Desktop.
Hibernate Native SQL Aliased Criterion
package org.xmedeko.hibernate;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.engine.TypedValue;
import org.hibernate.type.Type;
import org.hibernate.util.ArrayHelper;
/**
* A SQL fragment. The string {alias} will be replaced by the alias of the root entity. Any other aliases or property
* names will be searched, if provided in {aliasName} manner.
*
* @author Sergey Pulyaev
* @author xmedeko
*
* @see http://opensource.atlassian.com/projects/hibernate/browse/HHH-2952
*/
public class NativeSQLAliasedCriterion implements Criterion {
private static final long serialVersionUID = -4025066009045126609L;
private final String sql;
private final TypedValue[] typedValues;
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return applyAliases(criteria, criteriaQuery);
}
private String applyAliases(Criteria criteria, CriteriaQuery criteriaQuery) {
StringBuilder res = new StringBuilder();
int i = 0;
int cnt = this.sql.length();
while (i < cnt) {
int l = this.sql.indexOf('{', i);
if (l == -1) {
break;
}
String before = this.sql.substring(i, l);
res.append(before);
int r = this.sql.indexOf('}', l);
String alias = this.sql.substring(l + 1, r);
if (alias.length() <= 0 || "alias".equals(alias)) { // root alias
res.append(criteriaQuery.getSQLAlias(criteria));
} else {
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, alias);
if (columns.length != 1)
throw new HibernateException("SQLAliasedCriterion may only be used with single-column properties: "
+ alias);
res.append(columns[0]);
}
i = r + 1;
}
String after = this.sql.substring(i, cnt);
res.append(after);
return res.toString();
}
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return typedValues;
}
@Override
public String toString() {
return sql;
}
/**
* Constructor.
* @param sql
* @param values
* @param types
*/
public NativeSQLAliasedCriterion(String sql, Object[] values, Type[] types) {
this.sql = sql;
typedValues = new TypedValue[values.length];
for (int i = 0; i < typedValues.length; i++) {
typedValues[i] = new TypedValue(types[i], values[i], EntityMode.POJO);
}
}
/**
* Constructor.
* @param sql
* @param value
* @param type
*/
public NativeSQLAliasedCriterion(String sql, Object value, Type type) {
this(sql, new Object[] { value }, new Type[] { type });
}
/**
* Constructor.
* @param sql
*/
public NativeSQLAliasedCriterion(String sql) {
this(sql, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment