diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index d5f590d8f..979c4cf0b 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -61,6 +61,7 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor; import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyLists; import io.ebeaninternal.server.el.ElComparator; import io.ebeaninternal.server.el.ElComparatorCompound; +import io.ebeaninternal.server.el.ElComparatorNoop; import io.ebeaninternal.server.el.ElComparatorProperty; import io.ebeaninternal.server.el.ElPropertyChainBuilder; import io.ebeaninternal.server.el.ElPropertyDeploy; @@ -2443,7 +2444,15 @@ public class BeanDescriptor implements BeanType, STreeType { private ElComparator createPropertyComparator(SortByClause.Property sortProp) { ElPropertyValue elGetValue = getElGetValue(sortProp.getName()); + if (elGetValue == null) { + logger.error("Sort property [" + sortProp + "] not found in " + beanType + ". Cannot sort."); + return new ElComparatorNoop<>(); + } + if (elGetValue.isAssocMany()) { + logger.error("Sort property [" + sortProp + "] in " + beanType + " is a many-property. Cannot sort."); + return new ElComparatorNoop<>(); + } Boolean nullsHigh = sortProp.getNullsHigh(); if (nullsHigh == null) { nullsHigh = Boolean.TRUE; diff --git a/src/main/java/io/ebeaninternal/server/el/ElComparatorNoop.java b/src/main/java/io/ebeaninternal/server/el/ElComparatorNoop.java new file mode 100644 index 000000000..9377aa91c --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/el/ElComparatorNoop.java @@ -0,0 +1,23 @@ +package io.ebeaninternal.server.el; + +/** + * Comparator with no operation for unsortable properties. + * + * @author Roland Praml, FOCONIS AG + * + */ +public class ElComparatorNoop implements ElComparator { + + private static final long serialVersionUID = -9060871822183687180L; + + @Override + public int compare(T o1, T o2) { + return 0; + } + + @Override + public int compareValue(Object value, T o2) { + return 0; + } + +} diff --git a/src/main/java/io/ebeaninternal/server/el/ElComparatorProperty.java b/src/main/java/io/ebeaninternal/server/el/ElComparatorProperty.java index 84f188167..d3ffb5aa2 100644 --- a/src/main/java/io/ebeaninternal/server/el/ElComparatorProperty.java +++ b/src/main/java/io/ebeaninternal/server/el/ElComparatorProperty.java @@ -2,6 +2,8 @@ package io.ebeaninternal.server.el; import java.util.Comparator; +import io.ebean.bean.EntityBean; + /** * Comparator based on a ElGetValue. */ @@ -42,9 +44,15 @@ public final class ElComparatorProperty implements Comparator, ElComparato if (val1 == null) { return val2 == null ? 0 : nullOrder; } + if (elGetValue.isAssocId()) { + val1 = elGetValue.getAssocIdValues((EntityBean) val1)[0]; // TODO: compound key not yet supported + } if (val2 == null) { return -1 * nullOrder; } + if (elGetValue.isAssocId()) { + val2 = elGetValue.getAssocIdValues((EntityBean) val2)[0]; + } Comparable c = (Comparable) val1; return asc * c.compareTo(val2); } diff --git a/src/main/java/io/ebeaninternal/server/el/ElPropertyChain.java b/src/main/java/io/ebeaninternal/server/el/ElPropertyChain.java index 7afd21a1f..c5a91e896 100644 --- a/src/main/java/io/ebeaninternal/server/el/ElPropertyChain.java +++ b/src/main/java/io/ebeaninternal/server/el/ElPropertyChain.java @@ -266,6 +266,9 @@ public class ElPropertyChain implements ElPropertyValue { @Override public Object pathGet(Object bean) { for (ElPropertyValue aChain : chain) { + if (aChain.isAssocMany()) { + throw new UnsupportedOperationException("pathGet not supported on [" + expression + "], because " + aChain + " is an assocMany property"); + } bean = aChain.pathGet(bean); if (bean == null) { return null;