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

Using Java 8 named parameter prevents positional query parameter binding [DATAJPA-758] #1129

Closed
spring-projects-issues opened this issue Jul 10, 2015 · 5 comments
Assignees
Labels
type: bug A general bug

Comments

@spring-projects-issues
Copy link

Michael Wiles opened DATAJPA-758 and commented

When I turned on parameter naming in the java 8 compiler all the non named parameters I have no longer work.

In other words, Spring Data JPA insists on using the parameter name...

Simple Example:

@Query("select r from Role r where ?1 member of r.permissions")
public List<Role> findByPermission(Permission permission);

Works fine without parameter names added to compiler.

When I turn on the inclusion of parameter names I get this error:

Using named parameters for method public abstract java.util.List com.xxx.RoleRepository.findByPermission(com.xxx.Permission) but parameter 'permission' not found in annotated query 'select r from AshesRole r where ?1 member of r.permissions'!

And if I now change it to:

@Query("select r from AshesRole r where :permission member of r.permissions")
public List<Role> findByPermission(Permission permission);

It works again...

This could be by design - I understand that if it is the case. i.e. when you turn on parameter name inclusion then you must name all your parameters.

A fall back to "non named" would be ideal if scanning with parameter names is not successful but that might be too much overhead.

Though another option would be to allow the user to turn off using named parameters even when available. Developers might require parameter names in classes for some unrelated purpose and turning it on would break all their JPA queries (as they have not used it up to now).

Maybe making it configurable per repository is an alternative...


Affects: 1.8.1 (Fowler SR1)

Issue Links:

  • DATACMNS-731 Parameter should expose whether it's explicitly named

Referenced from: commits 8de3100, e8e8e1b, 7796165, 0cbfefc

Backported to: 1.8.2 (Fowler SR2)

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

Good catch! I've just pushed a patch that basically skips the parameter validation if we find the query is not using named parameters at all. Feel free to give the snapshots a spin

@spring-projects-issues
Copy link
Author

Michael Wiles commented

Yes, this particular issue has been addressed...

However the following scenario still persists... This might need another JIRA:

@Query("select r from Role r where ?1 member of r.permissions")
    public List<Role> findByPermission(Permission permission);

Works when parameter names are enabled and on 1.8.2.BUILD-SNAPSHOT (This did not work before).

But what doesn't work is the following:

public Tenant findByKey(String key);

It is rejected with exception:

Caused by: java.lang.IllegalArgumentException: reserved word key is not valid

The same can be replicated by adding @Param("key") on 1.8.1.RELEASE without include parameter names:

So ```java
public Tenant findByKey(@Param("key") String key);


Now I understand that this may only be an OpenJpa issue but I wouldn't be surprised if other JPA implementations have a constraint on parameter names.

It seems that when parameter names are available whether by java 8 or not they are generated and validated. It would be unfortunate if developers were forced to use parameter names that are valid on the JPA implementation especially for generated queries.

I guess if they explicitly use parameter names it would be potentially acceptable if they were forced to use valid parameter names.

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

I gave it another spin and tweaked the default behavior slightly. We're now able to detect whether a parameter has been explicitly named (i.e. annotated) and only then use the by-name binding. This is to make sure that if a user uses @Param, that annotation actually gets applied (it would be confusing if not). This is in both master (Gosling) and 1.8.x (Fowler) so feel free to give it another chance

@spring-projects-issues
Copy link
Author

Michael Wiles commented

Thanks. Tested and Works.

Error on ```java
public Tenant findByKey(String key);


And using     
```java 
@Query("select r from Role r where :permission member of r.permissions")
public List<Role> findByPermission(Permission permission); ```
 Works great.

@spring-projects-issues
Copy link
Author

Oliver Drotbohm commented

Awesome, thanks!

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

No branches or pull requests

2 participants