-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Dataes 631 consolidate query objects #340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dataes 631 consolidate query objects #340
Conversation
efd592e
to
b23cfae
Compare
e0224eb
to
ee19280
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR isn't addressing shortcomings of SearchQuery
and its coupling to the driver types. Also, we miss the mapping and conversion of values in CriteriaQuery
. A query mapper should apply mapping of criteria expression (property/property path and value) against the domain model. A transition of the final, mapped criteria should happen in a different place.
Looking at SearchQuery
I strongly feel we should remove that interface entirely and keep NativeSearchQuery
as NativeSearchQuery
honestly expresses what it is.
On Query
, we should remove the generics at setPageable
and addSort
. A revision of Query
should be done in its own ticket, but that is something I spotted while going over Query
that method names are not consistent, and in some places, we offer a fluent API possibility, and in others, we don't.
I would suggest doing the following in the scope of this ticket:
- Remove
SearchQuery
interface - Move the code from the created query mappers into a
SearchRequestFactory
that takes all sorts of queries and translates these into aSearchRequest
. - Optionally: A Query mapper that takes a
CriteriaQuery
and maps and converts values against the domain model (map property names to field names, apply value conversion by consideringCustomConversions
)
@@ -339,34 +330,20 @@ | |||
* @param clazz | |||
* @return | |||
*/ | |||
<T> long count(CriteriaQuery query, Class<T> clazz); | |||
<T> long count(Query query, @Nullable Class<T> clazz); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Query
currently carries types and indices. Typically, we keep these table-like coordinates on method level so a Query
object can be applied to various (tables/collections/)indices. I wonder whether it would make sense to extract indices/types into a type that holds both information. We could then add these coordinates to count(…)
via count(Query, Class<?>, Index...)
. That way, we separate the actual criteria from execution-specific targets.
Ideally, we can expose count
with the following overloads:
long count(Query query, Class<?> entityClass);
long count(Query query, Index... indexes);
long count(Query query, @Nullable Class<?> entityClass, Index... indexes);
We should also drop the generic type T
as there's no outbound usage of T
.
* @author Peter-Josef Meisch | ||
* @since 4.0 | ||
*/ | ||
public abstract class AbstractQueryMapper<R> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably don't want a generic type as the query mapper should always return a concrete type that can be used with the store. There's probably not much value in sharing an AbstractQueryMapper
across the Rest and the Transport Client implementation.
94290ab
to
856ef16
Compare
@mp911de: next iteration: I moved the The There now is a What I have not started to implement is the QueryMapper, part of this mapping is already contained for example in the
Am I going in the right direction? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change is definitively going in the right direction. I left a few comments about some high-level issues. Great work!
* @return | ||
*/ | ||
<T> long count(CriteriaQuery query); | ||
default long count(Query query, @Nullable Class<?> clazz) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, we can make the entity class non-nullable (if we manage getting rid of the index coordinates inside of Query
).
* Value object encapsulating index name(s) and index type(s). | ||
* | ||
* @author Mark Paluch | ||
* @author Christoph Strobl @author Peter-Josef Meisch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Line break, @since
private final String[] indexNames; | ||
private final String[] typeNames; | ||
|
||
public IndexCoordinates(String[] indexNames) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make constructors private
so creation works only using static factory methods and mutators (of(…)
, withIndex(…)
, withType(…)
).
* @author Peter-Josef Meisch | ||
* @since 4.0 | ||
*/ | ||
public class SearchRequestFactory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep that type package-protected.
} | ||
} | ||
|
||
private Pair<QueryBuilder, QueryBuilder> getQueryAndFilter(Query query) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's resolve the need for a Pair
by splitting that method into two methods.
} | ||
|
||
@Nullable | ||
private String[] retrieveIndexNameFromPersistentEntity(@Nullable Class clazz) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The class should be non-nullable and we should use getRequiredPersistentEntity(…)
to avoid NPEs.
This method is called when we do not have index coord specified, so having a persistent entity is a requirement. Same for retrieveTypeFromPersistentEntity
.
1a3333d
to
d1d09af
Compare
19da170
to
f5f4a33
Compare
I'm making progress. The work is not complete yet. What I did up to now:
I'm not yet content with the many calls of If you find the time please have a look. |
The default Travis environment does not provide Java 8 anymore. Only the older Travis environments come with Java 8. We're currently in the process of enabling Spring Data builds (the build itself, using Spring Data on Java9+ works for quite some time) on Java 11. There's a branch and build that work on Java 11 with |
b738155
to
f5814df
Compare
I think it's time to merge this |
this.indexNames = indexNames; | ||
} | ||
|
||
public IndexCoordinates withTypes(String... typeNames) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's follow the immutable approach and create a new instance of IndexCoordinates
here so IndexCoordinates
can be used as a fully immutable object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty decent. I second your opinion that we should merge that PR to not lose more focus. I left a few comments around IndexCoordinates
as the class was used previously internally. Now that it's public API, we should make it safe to use.
Feel free to merge this PR afterward. Great work!
private String[] typeNames = new String[0]; | ||
|
||
public static IndexCoordinates of(String... indexNames) { | ||
Assert.notNull(indexNames,"indexNames must not be null"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also ensure that indexNames
contains at least one element so we can get rid of nullability in getIndexName()
return indexNames; | ||
} | ||
|
||
public String getTypeName() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: @Nullable
return indexNames != null && indexNames.length > 0 ? indexNames[0] : null; | ||
} | ||
|
||
public String[] getIndexNames() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure, we might want to return a copy of the array to prevent mutation (e.g getIndexNames()[0] = "foo"
)
f5814df
to
3e8db01
Compare
Draft PR.