Affects: 3.3.2 / main branch


In the JdbcClient.MappedQuerySpec, the docs and method contract conveys that .single() can never return null. Except it can, but because the docs/method contract says it can't, my IDE complains.

If I have a thingies table that looks like this:

id thingy
1 "Something"
2 null

and then execute the following:

String thingy = jdbcClient.sql("SELECT thingy FROM thingies WHERE id = :id")
        .param("id", "2")
        .query(String.class)
        .single();

assert thingy == null;
// IDE complains: Condition 'thingy == null' is always 'false'
// Actual result is 'true', so the IDE is wrong, but the IDE is basing it's information on the method contract.

Offending docs line: https://github.com/spring-projects/spring-framework/blob/main/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/JdbcClient.java#L399

Not sure how the method contract works it out, as I'm not au fait with the Spring Framework code base.

I don't mind this behaviour being what it is, but I would prefer the method contract/docs to reflect that the method can return null values when the value in the DB is null, so that the IDE doesn't complain.

Comment From: jhoeller

The intention is a guaranteed non-null value from single(). However, due to the unspecified nullness of collections (with no constraints applied by IntelliJ IDEA and NullAway inspections), we missed to enforce this. If you need null as a potential result value there, please call optional() instead of single().

I'm adding an not-null assertion to DataAccessUtils.requiredSingleResult (which JdbcClient is delegating to there) as well as DataAccessUtils.requiredUniqueResult. However, due to current user code potentially accidentally relying on a null value in certain cases, we are only going to enforce this in 6.2 (with RC1 coming up in September, GA in November).

Comment From: Harmelodic

The intention is a guaranteed non-null value from single() ... If you need null as a potential result value there, please call optional() instead of single().

Roger that! 👍 Thanks for the attention on the issue. I appreciate your efforts 🤗