[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3704?page=c...
]
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....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira