[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2629?page=c...
]
John Newman commented on HHH-2629:
----------------------------------
Hi,
Any idea when this will get looked at? I thought I had a pretty good workaround here, and
it's been working fine for combinations of entities/embeds, but I broke it yesterday
with order by embeddedId > entity > string ..
public Criteria newCriteria(Order... orderBy) {
Criteria criteria = getSession().createCriteria(getEntityClass());
prepareCritiera(criteria, orderBy);
return criteria;
}
private void prepareCritiera(Criteria criteria, Order... orderBy) {
if (orderBy != null) {
for (Order order : orderBy) {
criteria.addOrder(criteriaHelper.reworkOrder(getEntityClass(),
criteria, order));
}
}
}
class CriteriaHelper {
public <E extends Entity<? extends Serializable>> Order
reworkOrder(Class<E> entityClass, Criteria criteria, Order order) {
String orderString = order.toString();
int spacePosition = orderString.indexOf(' ');
String newOrderString = reworkCriteria(entityClass, criteria, orderString
.substring(0, spacePosition));
return "asc".equalsIgnoreCase(orderString.substring(spacePosition + 1)) ?
Order
.asc(newOrderString)
: Order.desc(newOrderString);
}
public <E extends Entity<? extends Serializable>> String
reworkCriteria(Class<E> entityClassParam,
Criteria criteria, String fullProp) {
StringBuilder newPropString = new StringBuilder();
Class<E> entityClass = entityClassParam;
String[] props = fullProp.split("\\.");
String previousAlias = null;
for (int i = 0; i < props.length; ++i) {
String prop = props[i];
boolean entity = isEntity(entityClass, prop);
boolean embedded = isEmbedded(entityClass, prop);
if ((entity || embedded) && i != props.length - 1) {
String alias = buildAlias(prop, i);
if (entity) {
criteria.createAlias(combine(previousAlias, prop), alias);
}
previousAlias = entity ? alias : combine(previousAlias, prop);
entityClass = reflectUtil.<E> getPropType(entityClass, prop);
} else {
newPropString.append(combine(previousAlias, prop));
}
}
return newPropString.toString();
}
private String buildAlias(String prop, int i) {
return prop + ALIAS_MARKER + i;
}
private String combine(String previousAlias, String prop) {
return (previousAlias == null ? "" : previousAlias + '.') + prop;
}
private <E extends Entity<? extends Serializable>> boolean
isEmbedded(Class<E> entityClass, String prop) {
return reflectUtil.getPropType(entityClass, prop).isAnnotationPresent(
javax.persistence.Embeddable.class);
}
private <E extends Entity<? extends Serializable>> boolean
isEntity(Class<E> entityClass, String prop) {
return reflectUtil.getPropType(entityClass, prop).isAnnotationPresent(
javax.persistence.Entity.class);
}
}
Enable ordering by association paths
------------------------------------
Key: HHH-2629
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2629
Project: Hibernate3
Issue Type: Patch
Components: query-criteria
Affects Versions: 3.2.4.sp1
Reporter: Jörg Heinicke
Attachments: CriteriaQueryTranslator.java.patch.txt
In Hibernate's criteria API ordering is not possible on association properties
without explicitly creating aliases.
This also only works on one level, not recursively as it would be needed in the following
example.
Criteria criteria = session.createCriteria(Account.class);
Criteria pCriteria = criteria.createCriteria("person");
pCriteria.add(Example.create(person));
pCriteria.createCriteria("company");
criteria.addOrder(Order.asc("person.company.name"));
return criteria.list();
I have changed CriteriaQueryTranslator in a way that it first searches the
aliasCriteriaMap, second the associationPathCriteriaMap. And the key used for the search
is no longer
StringHelper.root( propertyName );
but
StringHelper.qualifier( propertyName );
From what I understand this can't break anything since it has always only worked with
one '.' in the path. For those cases the key stays the same.
This implementation is still not perfect since
1. you need to create criteria in advance
2. you can't switch between alias and actual association path. The best would
probably be to walk the path recursively.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira