Hi,
I'm currently trying to use a <t:commandSortHeader> Tomahawk tag inside
<t:column defaultSorted="true" sortable="true"> with auto sorting,
similar to the example here:
https://wiki.apache.org/myfaces/Working_with_auto_sortable_tables
Problem is, the tag's "propertyName" references to a string property of
an attribute of a given entity object (which itself does not extend
BaseSortableModel) and the entity's attribute is optional (nullable),
which will lead to a NestedNullException:
ERROR [org.apache.myfaces.component.html.ext.SortableModel]...
org.apache.commons.beanutils.NestedNullException: Null property value
for 'attribute.shortName' on bean class 'class
com.my.app.model.food.exotic.fruit'
...
javax.faces.FacesException: java.lang.IllegalArgumentException:
Comparison method violates its general contract!
at
javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2352)
...
Caused by: java.lang.IllegalArgumentException: Comparison method
violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:777) [rt.jar:1.8.0_60]
at java.util.TimSort.mergeAt(TimSort.java:514) [rt.jar:1.8.0_60]
at java.util.TimSort.mergeCollapse(TimSort.java:439)
[rt.jar:1.8.0_60]
at java.util.TimSort.sort(TimSort.java:245) [rt.jar:1.8.0_60]
at java.util.Arrays.sort(Arrays.java:1512) [rt.jar:1.8.0_60]
at java.util.ArrayList.sort(ArrayList.java:1454) [rt.jar:1.8.0_60]
at java.util.Collections.sort(Collections.java:175)
[rt.jar:1.8.0_60]
at
org.apache.myfaces.component.html.ext.BaseSortableModel.sort(BaseSortableModel.java:201)
[tomahawk20-1.1.14.jar:1.1.14]
at
org.apache.myfaces.component.html.ext.BaseSortableModel.setComparator(BaseSortableModel.java:62)
[tomahawk20-1.1.14.jar:1.1.14]
at
org.apache.myfaces.component.html.ext.SortableModel.setSortCriteria(SortableModel.java:143)
[tomahawk20-1.1.14.jar:1.1.14]
at
org.apache.myfaces.component.html.ext.AbstractHtmlDataTable.createDataModel(AbstractHtmlDataTable.java:1643)
[tomahawk20-1.1.14.jar:1.1.14]
at
org.apache.myfaces.component.html.ext.HtmlDataTableHack.getDataModel(HtmlDataTableHack.java:932)
[tomahawk20-1.1.14.jar:1.1.14]
at
org.apache.myfaces.component.html.ext.AbstractHtmlDataTable.getDataModel(AbstractHtmlDataTable.java:1597)
[tomahawk20-1.1.14.jar:1.1.14]
at
org.apache.myfaces.component.html.ext.HtmlDataTableHack.getRowCount(HtmlDataTableHack.java:103)
[tomahawk20-1.1.14.jar:1.1.14]
at sun.reflect.GeneratedMethodAccessor32969.invoke(Unknown Source)
[:1.8.0_60]
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[rt.jar:1.8.0_60]
at java.lang.reflect.Method.invoke(Method.java:497)
[rt.jar:1.8.0_60]
...
As I understand it, the row Objects of a sortable <t:dataTable> column
are being automatically wrapped in SortableModel, which brings its own
"RowDataComparator" via BaseSortableModel.sort(), which seems to be
a) not null-safe (for the wrapped model)
b) not supporting nulls first/last
c) in this case violating the Comparator contract
Regardless of the contract violation problem (probably due to a
NestedNullException inside RowDataComparator or because
BaseSortableModel.sort() never returning -1), I'd like in general to be
able to use a custom Comparator here, which can handle nested nulls and
implements a customized comparison, but <t:commandSortHeader> does not
seem to support this.
Most references I find, completely ignore the commandSortHeader
auto-sorting and do the implement a custom backing Bean.sort(), an
approach I'd like to avoid, if possible.
There would seem to exist a solution for the problem in this somewhat
dated example here, but it's unclear to me, if it ever managed to make
it into tomahawk's code base:
http://grokbase.com/t/myfaces/dev/073ev810b8/sortablemodel-and-t-datatable-changes-improvements
In Trinidad, it would seem, that there was a similar (now resolved)
issue:
https://issues.apache.org/jira/browse/TRINIDAD-1965
I could not figure out how this applies to Tomahawk, though, or if the
example above has been implemented by now, and I could not find any
working code example that would support this assumption.
Also, I do not see how SortableModel.setSortCriteria() ->
BaseSortableModel.setComparator() could be utilized in this scenario
without letting the entity model extend BaseSortableModel or
SortableModel, which seems not feasable, due to my model already
extending several other classes. Is using a custom Comparator not
supported in Tomahawk still, or, if so, where can I find code examples
or documentation describing how to use this feature?
If not, are you planning on fixing this issue anytime soon and should I
file a bug about the NestedNullException / contract violation problem,
too?
Best regards,
Sawin