Skip to content
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

Cannot use a parameter of type Class in custom queries #2510

Closed
alienisty opened this issue Dec 9, 2021 · 3 comments
Closed

Cannot use a parameter of type Class in custom queries #2510

alienisty opened this issue Dec 9, 2021 · 3 comments
Assignees
Labels
type: documentation A documentation update

Comments

@alienisty
Copy link

alienisty commented Dec 9, 2021

If a query method with custom query uses a parameter of type Class annotated with @param("name"), it is considered a dynamic projection parameter and it is not bound to the query parameter.
For example, for a polymorphic entity E, I would like to be able to express a query such as:

  @Query("from E e where type(e) = :type")
  <T> List<T> findAll(@Param("type") Class<T> type);
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 9, 2021
@mp911de
Copy link
Member

mp911de commented Dec 9, 2021

This is by design as the Class<T> parameter is considered a special parameter that is not made available for query binding. You can add another Class<?> argument to bind it into the query.

@alienisty
Copy link
Author

alienisty commented Dec 9, 2021

I think that should be documented then. By the principle of least surprise, I would expect that any method parameter annotated with @param would be bound to the provided named parameter in the custom query, as a user I had to dig quite a bit to understand why the framework was complaining about the pameter not being bound. I believe that most users would not have the understanding of that detail of the design.

The other weird thing is that I could use the following signature:

  @Query("from E e where type(e) in :type")
  <T> List<T> findAll(@Param("type") Class<T> ... type);

and that works as one would expect and projections do not get in the way, except it is a misuse of varargs and you get a nice heap pollution warning for it.

I believe that if a parameter of type Class is annotated with @param, it should not be considered a dynamic projection parameter (Parameter.isDynamicProjectionParameter() should return false). If I wanted to use a projection in my use case, then I would be using two parameters of type Class as you seggested as:

  @Query("from E e where type(e) = :type")
  <P> List<P> findAll(@Param("type") Class<?> type, Class<P> projection);

which, in my opinion, many users of the framework would find quite intuitive and consistent with the rest of the framework as it is currently documented.

Note, I can workaround this by using repository customizations, which is OK, but it would be nicer if you could add direct support.

@schauder schauder added type: documentation A documentation update and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 24, 2022
mp911de added a commit that referenced this issue Jan 25, 2022
mp911de added a commit that referenced this issue Jan 25, 2022
mp911de added a commit that referenced this issue Jan 25, 2022
@mp911de mp911de added this to the 2.5.9 (2021.0.9) milestone Jan 25, 2022
@mp911de
Copy link
Member

mp911de commented Jan 25, 2022

We added a bit of documentation of how Class-parameters are handled during query execution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: documentation A documentation update
Projects
None yet
Development

No branches or pull requests

4 participants