Introduce first-class type-safe property path references at the core level#3409
Introduce first-class type-safe property path references at the core level#3409
Conversation
schauder
left a comment
There was a problem hiding this comment.
Looks great. I left a few nitpicks.
I didn't look into actually using it, since it seems Christoph already did that.
Let me know if I should take it for a spin as well.
| This chapter covers the concept of property paths. | ||
| Property paths are a form of navigation through domain classes to apply certain aspects in the context of interacting with the model. | ||
| Application code provides property paths to data access components to express intents such as selection of properties within a query, forming predicates, or applying sorting. | ||
| A property path originates from its owning type and can consist of one to many segments. |
There was a problem hiding this comment.
"one to many segments"
I know, I lost the fight before, but I still find it really weird, that we don't have zero length paths, referring to the a aggregate root itself.
There was a problem hiding this comment.
A zero-length-path that would describe its object root isn't a property path.
| * This method returns a resolved {@link PropertyReference} by introspecting the given method reference. | ||
| * | ||
| * @param property the method reference to a Java beans property. | ||
| * @param <T> owning type. |
There was a problem hiding this comment.
Could we improve readability a little by using something more mnemonic than T? Or am I missing something?
O for Orgin or Owner.
R for Root
S for Source
Applies also for TypedPropertyPath
There was a problem hiding this comment.
T is a short variant for Type in alignment with Optional<T>, Function<T> and the like. O for the owner seems an okay match as well.
| @Contract("_ -> new") | ||
| @CheckReturnValue | ||
| default <T> ExampleMatcher withIgnorePaths(TypedPropertyPath<T, ?>... ignoredPaths) { | ||
| return withIgnorePaths(Arrays.stream(ignoredPaths).map(TypedPropertyPath::of).map(TypedPropertyPath::toDotPath) |
There was a problem hiding this comment.
Why are we mapping it explicitly to TypedPropertyPath? This happens already in the getSegment called inside toDotPath.
If this is for performance reasons (just guessing) we should add a comment to that effect .
There was a problem hiding this comment.
This pattern appears a couple of times.
There was a problem hiding this comment.
Good catch. Initially, that was a fix for performance reasons. Default property path methods now handle of(this) themselves so the wrapping isn't necessary anymore.
| * | ||
| * @author Mark Paluch | ||
| */ | ||
| class PropertyPathTck { |
There was a problem hiding this comment.
I'm a little confused by the name TCK. This seems more like a PropertyPathTestSupport.
From a TCK I would expect that it actually forces you to provide certain propertyPaths.
Maybe as a Map from a String representation to the representation under test and then run a bunch of tests against these, and failing when expected paths aren't in the provided Map.
There was a problem hiding this comment.
The TCK is an abbreviation for test compatibility kit.
We now support type-safe property paths and property references:
Java variants:
PropertyPath.from("name", Person.class) // existing String-based API
PropertyPath.of(Person::getName) // type-safe property reference expression
PropertyPath.from("address.country", Person.class) // existing nested path API
PropertyPath.of(Person::getAddress).then(Address::getCountry) // type-safe composed path expression
PropertyReference.of(Secret::getSecret)
Kotlin variants:
PropertyReference.of(Secret::secret)
PropertyPath.of(Person::address / Address::city)
allowing type-safe usage through e.g.:
Sort.by(Person::getFirstName, Person::getLastName)
Closes #3400
We now support type-safe property paths and property references:
Java variants:
PropertyPath.from("name", Person.class) // existing String-based API
PropertyPath.of(Person::getName) // type-safe property reference expression
PropertyPath.from("address.country", Person.class) // existing nested path API
PropertyPath.of(Person::getAddress).then(Address::getCountry) // type-safe composed path expression
PropertyReference.of(Secret::getSecret)
Kotlin variants:
PropertyReference.of(Secret::secret)
PropertyPath.of(Person::address / Address::city)
allowing type-safe usage through e.g.:
Sort.by(Person::getFirstName, Person::getLastName)
Closes: #3400
Original Pull Request: #3409
Original Pull Request: #3409
We now support type-safe property paths and property references:
Java variants:
Kotlin variants:
allowing type-safe usage through e.g.:
Module adoption:
Expressionsutility for type-safe Criteria Query Expression resolution spring-data-jpa#4086QueryandUpdateAPI acceptingTypedPropertyPathspring-data-cassandra#1626