jakartaee / data

Data-API
Apache License 2.0
105 stars 29 forks source link

Can null values be supplied as parameters to repository methods? #98

Open njr-11 opened 1 year ago

njr-11 commented 1 year ago

A user might try to invoke repository methods by sending a null parameter value. For example,

findByFirstName(null)
findByFirstNameLike(null)
getAllNamed(null) // annotated with @Query("SELECT o FROM Person o WHERE o.firstName=?1")
findByPlacesWorkedContains(null)
findByAgeBetween(null, max)

Which of these, if any, should be allowed? And if allowed, what is the behavior?

The simplest thing to do would be to state that null parameters aren't allowed and are rejected with an exception (maybe IllegalArgumentException and require the user to write the repository methods another way, such as,

findByFirstNameNull() // for the first 3 examples above
findByAgeLessThan(max) // for the last example above

Or the specification could allow null for some patterns, but not all.

If null is allowed for any, then we need to define what it means.

JPQL has the following behavior for null values, which many users of a repository pattern would not expect because they are thinking of Java nulls upon which == can be used. In JPQL,

Two NULL values are not equal.

If a user defines a repository method with @Query specifying a JPQL query and supplies a null parameter to it, I think we are limited to either giving them the JPQL-defined behavior for it or rejecting the null. I don't think we can or should require Jakarta Data providers to rewrite user-defined JPQL to make it mean something else.

A method like findByFirstName(null) is less clear. The Jakarta Data specification could state that a null parameter in this case gets interpreted to have the behavior of findByFirstNameNull(). Some users might find that convenient, mainly if the value being null vs non-null will vary so they don't know in advance. The tradeoff is that it puts extra burden on the Jakarta Data provider and likely requires recomputing queries when the method is invoked in response to parameter values, or if computed in advance, there could be many permutations of queries needed due to the presence of multiple nullable parameters.

mp911de commented 1 year ago

null makes sense on its own, except for the following comparisons:

In this context, it also makes sense to mention that Optional.empty() maps to null in Spring Data as those discussions often go together.

graemerocher commented 1 year ago

but Optional shouldn't be used for method parameters?