Skip to content

Insufficient documentation for Value expressions #3688

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

Closed
sergey-morenets opened this issue Nov 24, 2024 · 7 comments
Closed

Insufficient documentation for Value expressions #3688

sergey-morenets opened this issue Nov 24, 2024 · 7 comments
Assignees
Labels
type: documentation A documentation update

Comments

@sergey-morenets
Copy link

Spring Data 3.4.0 brings new feature - Value Expressions (#3619)

However the latest documentation section(https://docs.spring.io/spring-data/jpa/reference/jpa/value-expressions.html) has only one example of the code:

@Document("orders-#{tenantService.getOrderCollection()}-${tenant-config.suffix}")
class Order {
  // …
}

This example is from Spring Data Mongo and can't be used for Spring Data JPA. Moreover the whole section is copied from Spring Data Mongo documentation without any changes (https://docs.spring.io/spring-data/mongodb/reference/mongodb/value-expressions.html)

So neither the documentation nor GitHub ticket have examples how to use new feature in Spring Data JPA. So it'd be nice to add few examples in the documentation.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 24, 2024
@mp911de
Copy link
Member

mp911de commented Nov 25, 2024

Usage of Config Properties is documented at https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html#jpa.query.spel-expressions at Example 20. Using Value Expressions in Repository Query Methods: Configuration Properties

Let me know what else you're looking for.

For JPA, the evaluation of annotation values is subject to JPA providers, where we cannot inject additional functionality. However, the mentioned page about Value Expressions is part of our common documentation.

Maybe the issue is that we created some over-expectation by our naming. Value Expressions are SpEL expressions plus Property Placeholders whereas we previously only supported SpEL expressions.

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Nov 25, 2024
@sergey-morenets
Copy link
Author

This section misses two important topics.

  1. What is the scope of this functionality? Examples demonstrate how we can use Value Expressions in @query annotation. Are there any other places (annotations) where can we use them?
  2. Example 2. Expression Examples includes this example:

#{tenantService.getOrderCollection()}

But if I try to use it in @query annotation (productService is bean id):

	@Query("""			
			FROM Product WHERE name=:name 
			and department=?#{productService.getDepartment()}""")
	Product findByName(String name);

then I receive an exception:
org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'productService' cannot be found on object of type 'java.lang.Object[]' - maybe not public or not valid?

So it's not clear whether we can access bean properties/methods in Value Expressions and if yes then how?

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 25, 2024
@mp911de
Copy link
Member

mp911de commented Nov 26, 2024

Documenting the scope makes sense. For the second issue, it works as designed.

It would make sense to call out that the default root object is the array of query method parameters when working with queries. Any beans must be accessed via ?#{#productService.getDepartment()} (note the missing # was added before productService).
Any other properties, variables and functions must be contributed by declaring a EvaluationContextExtension as per documentation.

By explaining scopes in the docs, we can make the second case more clear.

@mp911de mp911de added type: documentation A documentation update and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Nov 26, 2024
@mp911de mp911de self-assigned this Nov 26, 2024
@sergey-morenets
Copy link
Author

@mp911de

Unfortunately your advise didn't help. I added #:

	@Query("""			
			FROM Product WHERE name=:name 
			and department=?#{#productService.getDepartment()}""")
	Product findByName(String name);

But now error is different:

org.springframework.expression.spel.SpelEvaluationException: EL1011E: Method call: Attempted to call method getDepartment() on null context object

Although productService bean is available in the application context.

@sergey-morenets
Copy link
Author

sergey-morenets commented Nov 28, 2024

@mp911de

I investigated and debugged this issue and it seems that it's not possible to access Spring beans using this construction:

?#{#productService.getDepartment()}

There's BeanResolver interface which JavaDocs clearly state that @ or & characters should be used instead of #:

/**
 * A bean resolver can be registered with the evaluation context and will kick in
 * for bean references: {@code @myBeanName} and {@code &myBeanName} expressions.
 *
 * <p>The {@code &} variant syntax allows access to the factory bean where relevant.
 *
 * @author Andy Clement
 * @since 3.0.3
 */
@FunctionalInterface
public interface BeanResolver {

So the correct construction is


	@Query("""			
			FROM Product WHERE name=:name 
			and department=?#{@productService.getDepartment()}""")
	Product findByName(String name);

@mp911de
Copy link
Member

mp911de commented Nov 29, 2024

Apologies, you're right with @ and &. Hash (#) is used for variable references.

@mp911de
Copy link
Member

mp911de commented Nov 29, 2024

The docs are updated and snapshot variants are available from https://docs.spring.io/spring-data/jpa/reference/3.4-SNAPSHOT/jpa/value-expressions.html.

Spring Data docs isn't the place to explain the syntax (i.e. accessing beans and other invariants), Spring Framework has a reference documentation and we've updated our links. That being said, I consider this ticket done.

@mp911de mp911de closed this as completed Nov 29, 2024
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

3 participants