Issue Details (XML | Word | Printable)

Key: CAY-705
Type: Bug Bug
Status: Closed Closed
Resolution: Won't Fix
Priority: Major Major
Assignee: Unassigned
Reporter: Marcin Skladaniec
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Cayenne

Ordering.sortList() does not work with null relationships

Created: 13/Nov/06 06:42 AM   Updated: 08/Feb/07 12:50 PM
Component/s: Cayenne Core Library
Affects Version/s: 3.0
Fix Version/s: None

Time Tracking:
Not Specified

Resolution Date: 01/Dec/06 09:40 AM


 Description  « Hide
When list is sorted with customOrdering.sortList(list), and sorting is based on the field from the relationship the exception is raised.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Andrus Adamchik added a comment - 13/Nov/06 02:32 PM
Hmm... From what I can tell this is expected behavior. if you want to order in memory on Painting.toArtist - how is it supposed to work? In other words there is no natural ordering sequence for an arbitrary entity.

Marcin Skladaniec added a comment - 01/Dec/06 02:08 AM
I would say, that if there is a key path like : "artist.name" and the sort is done on painting, than if sort gives the null value for artist, than the whole value should be null. Example:

Paintings
painting id | artist id | artist name
1 | 1 | "Picasso"
2 | 2 | "Chagal"
3 | null |
4 | 3 | null

 
ascending sort on artist.name should give out the list like (painting ids) : 3,4,2,1 (or 4,3,2,1)

Right now it throws exception:

Exception in thread "AWT-EventQueue-0" org.apache.cayenne.exp.ExpressionException: [v.3.0-incubating-SNAPSHOT ] Error evaluating expression 'room.name'
        at org.apache.cayenne.exp.parser.SimpleNode.evaluate(SimpleNode.java:271)
        at org.apache.cayenne.query.Ordering.compare(Ordering.java:177)
        at java.util.Arrays.mergeSort(Arrays.java:1284)
        at java.util.Arrays.mergeSort(Arrays.java:1296)
        at java.util.Arrays.mergeSort(Arrays.java:1296)
        at java.util.Arrays.sort(Arrays.java:1223)
        at java.util.Collections.sort(Collections.java:159)
        at org.apache.cayenne.query.Ordering.orderList(Ordering.java:167)
...
Caused by: org.apache.cayenne.CayenneRuntimeException: [v.3.0-incubating-SNAPSHOT ] Null value in the middle of the path
        at org.apache.cayenne.property.PropertyUtils.getProperty(PropertyUtils.java:75)
        at org.apache.cayenne.exp.parser.ASTObjPath.evaluateNode(ASTObjPath.java:49)
        at org.apache.cayenne.exp.parser.SimpleNode.evaluate(SimpleNode.java:267)
        ... 36 more

Marcin Skladaniec added a comment - 01/Dec/06 02:42 AM
What about changing the evaluateNode in org.apache.cayenne.exp.parser.ASTObjPath.java
from :
protected Object evaluateNode(Object o) throws Exception {
        return (o instanceof DataObject)
            ? ((DataObject) o).readNestedProperty(path)
            : (o instanceof Entity)
            ? evaluateEntityNode((Entity) o)
            : PropertyUtils.getProperty(o, path);
    }

to:
protected Object evaluateNode(Object o) throws Exception {
        return (o == null ) ? null : (o instanceof DataObject)
            ? ((DataObject) o).readNestedProperty(path)
            : (o instanceof Entity)
            ? evaluateEntityNode((Entity) o)
            : PropertyUtils.getProperty(o, path);
    }

?
This would fix the problem, wouldn't it ?

Marcin Skladaniec added a comment - 01/Dec/06 03:13 AM
one last comment: It would be nice to have an option to set the ordering to sort the NULLs at the top/bottom of the list.
something like ordering.setNullValuesFirst(false);

Andrus Adamchik added a comment - 01/Dec/06 09:40 AM
Ah ok, this is about ordering on regular properties of related objects, not the relationships themselves.

Null handling in paths is more of a philosophical question (so that's something to discuss on cayenne-devel :-)). The behavior you describe is not a bug, it is how things work by design. Null handling when traversing property paths varies in different frameworks. EOF/WebObjects would simply return null, while Tapestry/OGNL would throw an exception. Cayenne follows the second approach.

Marcin Skladaniec added a comment - 01/Dec/06 11:18 AM
Ok.
Cant cayenne have both ? that is can there be another flag in the Ordering where to return null or throw exception ?
What is the benefit of throwing exception ? Sorting is meant to happen on null values, and null in the path is just one more null.
See there is no simply way of handling that exception, for me it is just annoyance. I would have to write a own sorting procedure and abandon org.apache.cayenne.query.Ordering at all.

Marcin Skladaniec added a comment - 08/Feb/07 12:50 PM
Is the "Resolution = Won't Fix" final ?
If so I have to work my way around.
 
Regards
Marcin