[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-2629) Enable ordering by association paths

John Newman (JIRA) noreply at atlassian.com
Tue Jun 10 15:58:36 EDT 2008


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2629?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_30390 ] 

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.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

       




More information about the hibernate-issues mailing list