[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-3704) Criteria Query on property of sandwich-like @MappedSuperclass fails. HQL works

Vikash Madhow (JIRA) noreply at atlassian.com
Tue Apr 7 07:28:37 EDT 2009


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3704?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=32811#action_32811 ] 

Vikash Madhow commented on HHH-3704:
------------------------------------

As a workaround, I've written the following method which automatically create the aliases when ordering by a property which references other entities. It works for property paths of any length, i.e., if you are ordering by a.b.c where b and c are entities, the method will create the alias for join a -> b and for b->c:

    /** Orders a criteria */
    protected Criteria order(Criteria query, Order... order) {
        try {
            for (Order ord: order) {
                // get order property and whether ascending or descending
                String property = ord.toString();
                int pos = property.lastIndexOf(' ');
                boolean asc = property.substring(pos + 1).trim().equalsIgnoreCase("asc");
                property = property.substring(0, pos).trim();

                // if property references other entities, create joins.
                // lastJoinPoint refers to the position in the property path 
                // where the last join was performed.
                Class currentClass = entityClass;
                Criteria subCriteria = query;
                StringBuilder currentPath = new StringBuilder();
                String[] paths = property.split("\\.");
                int lastJoinPoint = 0;

                for (int i = 0; i < paths.length - 1; i++) {
                    if (currentPath.length() != 0)
                        currentPath.append('.');
                    currentPath.append(paths[i]);

                    // Create a join for the current property path if it 
                    // references an entity class
                    property = currentPath.toString();
                    Class<?> type = FieldNavigator.getField(property, currentClass).getType();
                    if (type.isAnnotationPresent(Entity.class)) {
                        subCriteria = subCriteria.createCriteria(property);
                        currentPath.delete(0, currentPath.length());
                        currentClass = type;
                        lastJoinPoint = i + 1;
                    }
                }

                // order subCriteria by path elements starting from last join point
                currentPath.delete(0, currentPath.length());
                for (int i = lastJoinPoint; i < paths.length; i++) {
                    if (currentPath.length() != 0)
                        currentPath.append('.');
                    currentPath.append(paths[i]);
                }
                property = currentPath.toString();
                subCriteria.addOrder(asc ? Order.asc(property) : Order.desc(property));
            }
            return query;
        }
        catch(Exception e) {
            throw new RuntimeException(
                "Could not apply order " + Arrays.toString(order) + " to query '" +
                query + "' over " + entityClass, e);
        }
    }

---
The method FieldNavigator.getField simply returns the field corresponding to the property path supplied. If anyone requires the source, I'll post it.

Simply call this method to order your criteria query instead of Criteria.addOrder.

> Criteria Query on property of sandwich-like @MappedSuperclass fails. HQL works
> ------------------------------------------------------------------------------
>
>                 Key: HHH-3704
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3704
>             Project: Hibernate Core
>          Issue Type: Bug
>          Components: query-criteria
>    Affects Versions: 3.3.1
>         Environment: hibernate 3.3.1, mysql 5.0.45
>            Reporter: Christian kalkhoff
>            Priority: Minor
>
> I have a hierarchy of @MappedSuperclasses, in my case:
> @MappedSuperclass class BaseEntity{...}
> @MappedSuperclass class NamedBaseEntity extends BaseEntity {...}
> @Entity class ConcreteEntity extends NamedBaseEntity {...}
> @Entity class AggregatingOtherEntity extends NamedBaseEntity {
>     ConcreteEntity concreteEntity;
> }
> BaseEntity holds property "id", NamedBaseEntity holds property "name". ConcreteEntity might have property "moonphase".
> If I create a Criteria search expression on AggregatingOtherEntity like
> eq("concreteEntity.id", 1L)
> that works.
> eq("concreteEntity.moonphase", "half decending") works either.
> BUT
> like("concreteEntity.name", "foobar")
> raises QueryException: 
> org.hibernate.QueryException: could not resolve property: concreteEntity.name of: AggregatingOtherEntity
> 	org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:67)
> 	org.hibernate.persister.entity.AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:82)
> 	org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:54)
> 	org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1377)
> 	org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:457)
> 	org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumnsUsingProjection(CriteriaQueryTranslator.java:417)
> 	org.hibernate.criterion.SimpleExpression.toSqlString(SimpleExpression.java:68)
> 	org.hibernate.criterion.LogicalExpression.toSqlString(LogicalExpression.java:62)
> 	org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:357)
> 	org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:113)
> 	org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:82)
> 	org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:91)
> 	org.hibernate.impl.SessionImpl.list(SessionImpl.java:1577)
> 	org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)
> 	[...]
> If I refactor the Criteria search to plain HQL (From AggregatingOtherEntity Where concreteEntity.name like 'half decending') it works. So there is a workaround.

-- 
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