Skip to content

SpelEvaluator.evaluate(…) fails with NullPointerException when an expression yields a null value #2904

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
rogeriomgatto opened this issue Jul 28, 2023 · 8 comments
Assignees
Labels
type: bug A general bug

Comments

@rogeriomgatto
Copy link

rogeriomgatto commented Jul 28, 2023

I'm trying to use SpEL to bind parameter values from DTOs like this, in a JDBC repository:

    @Query(" ........ :#{#route.timestamp} .......")
    fun updateRoute(driverId: UUID, route: Route): Instant?

When any property is null, an NPE is thown in org.springframework.data.repository.query.SpelEvaluator because it uses Collectors.toMap and it doesn't support null values.

Also, there is no convertion to database types, for example an Instant value isn't converted to java.sql.Timestamp and sql execution fails.

I managed to fix both issues locally (I think):

  • In spring-data-commons
    • patched SpelEvaluator to gather TypeInformation using Expression::getValueTypeDescriptor
    • introduced a version of evaluate that returns a vo with both value and TypeInformation
    • got rid of the NPE by doing the collection manually instead of using Collectors.toMap
  • In spring-data-jdbc:
    • patched StringBasedJdbcQuery to use the new method from SpelEvaluator
    • passed values and TypeInformation through convertAndAddParameter instead of adding directly to the MapSqlParameterSource

How should I proceed to send the PRs, since they involve two projects?

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

mp911de commented Aug 7, 2023

Can you please provide a reproducer and attach the stack trace so we can better understand where the issue comes from?

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Aug 7, 2023
@spring-projects-issues
Copy link

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@spring-projects-issues spring-projects-issues added the status: feedback-reminder We've sent a reminder that we need additional information before we can continue label Aug 14, 2023
@rogeriomgatto
Copy link
Author

I have provided a test case in this repository: https://github.com/rogeriomgatto/minimal-test-case-1577

The following tests reproduce the bugs, the other tests are just to confirm everything else is ok:

I also uploaded my proposed fixes, and can provide pull requests, I just don't know how to proceed since one PR depends on the other. Should I just open them?

To test with the proposed changes, clone both repositories, checkout branch gh-1577-spring-data-relational, and mvn install. Uncomment the dependencyManagement blocks in minimal-test-case-1577 and run tests again, everything passes.

@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 status: feedback-reminder We've sent a reminder that we need additional information before we can continue labels Aug 16, 2023
@rogeriomgatto
Copy link
Author

Forgot the stack traces.

NPE.txt

BadSqlGrammarException.txt

@mp911de
Copy link
Member

mp911de commented Aug 16, 2023

Thanks a lot. The problem is being caused by SpelEvaluator that resides in Spring Data Commons. Let me move this ticket to the right project and fix it there.

@mp911de mp911de transferred this issue from spring-projects/spring-data-relational Aug 16, 2023
@mp911de mp911de changed the title NPEs and convertion problems when using SpEL parameter binding with @Query SpelEvaluator.evaluate(…) fails with NullPointerException when an expression yields a null value Aug 16, 2023
@mp911de mp911de added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Aug 16, 2023
@mp911de
Copy link
Member

mp911de commented Aug 16, 2023

Regarding the conversion issue, we never added conversion support to String-based queries. It would make sense to run binding values by the QueryMapper. Can you file a new ticket in Spring Data Relational?

@mp911de mp911de self-assigned this Aug 16, 2023
@mp911de mp911de added this to the 2.7.15 (2021.2.15) milestone Aug 16, 2023
mp911de added a commit that referenced this issue Aug 16, 2023
SpelEvaluator now iterates over the parameter map instead of using the Java 8 Stream API. Previously, expressions resulting in a null value failed in the collector as Java 8 streams require non-null values for map values.

Closes #2904
mp911de added a commit that referenced this issue Aug 16, 2023
SpelEvaluator now iterates over the parameter map instead of using the Java 8 Stream API. Previously, expressions resulting in a null value failed in the collector as Java 8 streams require non-null values for map values.

Closes #2904
mp911de added a commit that referenced this issue Aug 16, 2023
SpelEvaluator now iterates over the parameter map instead of using the Java 8 Stream API. Previously, expressions resulting in a null value failed in the collector as Java 8 streams require non-null values for map values.

Closes #2904
@rogeriomgatto
Copy link
Author

Thanks for the fix!

Regarding the conversion issue, we never added conversion support to String-based queries. It would make sense to run binding values by the QueryMapper. Can you file a new ticket in Spring Data Relational?

For string queries in general, there is conversion support when using "regular" parameter binding, just not for SpEL expressions, right? In my test cases, regular parameters of type java.time.Instant are properly converted before being sent to the database. Should I open the new issue as "Add conversion support for SpEL parameters in string queries"?

@mp911de
Copy link
Member

mp911de commented Aug 18, 2023

Yes, please.

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

3 participants