I'd like to apply Sort to Collection or Stream. Thanks to reflection it's possible to convert each Sort.Order to Comparator and then chain them into one. And then use this Comparator as parameter for Stream.sorted method
Thanks for the ticket. That is an interesting thought. We never evaluated really in-memory processing of data and having a Comparator built from Sort could nicely fit into our Streamable efforts. I'm going to take this ticket to our team to get other opinions
As I might not be properly available in the team call this afternoon, some thoughts on this. I fundamentally like the idea of a Sort being able to be used sorting a collection. It's also in proximity of what Querydsl already allows with it's collection querying capabilities. In case of use with TypedSort we might even be able to directly use the method handles given to perform the invocation although it currently resolves the referred to properties to strings eagerly, which would have to change for that.
I also see a couple of other risks:
Especially to beginners it creates incentives to query all data and apply sorting later that it would actually make sense (probable, but niche part of the audience, something we might want to accept)
The suggested implementation uses PropertyDescriptor instances and reflectively invokes the read methods. That's basically a parallel implementation of what we have in PersistentEntity with PersistentPropertyAccessor etc. It's a parallel implementation that works slightly different in a subtle way which probably creates confusion and suffers from repeated reflection overhead. Unfortunately, using the mapping information from our MappingContext is rather involved, is not something a user usually interacts with.
Especially the latter makes me think that we're looking at something that looks easy on the surface but bears quite a bit of unanticipated complexity.
Edit: looking at the PR, it looks like that helper class to create Comparator instances could easily just live outside Spring Data in a user's project in case one would need this for now
I second Ollie's opinion here. At first sight, it's a neat extension. I also share the main concern regarding property accessors. This utility would require to be tied to MappingContext which comes with its own rules. E.g. @Transient properties would not be included. Adding another approach to property access asks for trouble.
To stick with a consistent way of retrieving properties, obtaining a Comparator would require an association with the MappingContext and therefore less convenient to use (e.g. MappingContext.getComparator(Sort))
Thanks for suggestions. I agree with your points for reusing existing property accessing functionality. I tried to orientate in PersistentEntity/PersistentPropertyAccessor/MappingContext but I've got lost there. Is it possible to explain it on more specific examples? I tried to use org.springframework.beans.BeanWrapperImpl but it looks it wasn't designed for such purpose (NullValueInNestedPathException)
There's hardly any way to make this work using the MappingContext abstraction as the mapping package already depends on the domain package and we'd either create a cyclic dependency if the new code lived in the domain package as well. Also, setting up a MappingContext is a store specific undertaking that requires inclusion of user configuration etc. I.e. it's not code that should live anywhere near user domain code in the first place.
We could probably find a solution but that would require significant rework of abstractions and packages and would probably still end up creating more complexity for all other use cases due to additional indirections