Consider the following code snippet:

        BasicDataSource datasource = new BasicDataSource();
        datasource.setDriverClassName("com.mysql.jdbc.Driver");
        datasource.setUrl("jdbc:mysql://127.0.0.1");
        datasource.setUsername("username");
        datasource.setPassword("password");

        NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(datasource);
        template.queryForObject("SELECT COUNT(*) FROM table_name WHERE key ='\'?'", EmptySqlParameterSource.INSTANCE, Integer.class);

When you run it the following exception is thrown:

org.springframework.dao.InvalidDataAccessApiUsageException: SQL [SELECT COUNT(*) FROM table_name WHERE key =''\?']: given 1 parameters but expected 0

Most likely this is due to the implementation of org.springframework.jdbc.core.namedparam.NamedParameterUtils#parseSqlStatement where skip the quoted parts of the statements using the skipCommentsAndQuotes method. However this implementation also treats escaped quote mark \' as end of skipped sequence, thus, the question mark is not stripped out, and further code:

                if (c == '?') {
                    int j = i + 1;
                    if (j < statement.length && (statement[j] == '?' || statement[j] == '|' || statement[j] == '&')) {
                        // Postgres-style "??", "?|", "?&" operator should be skipped
                        i = i + 2;
                        continue;
                    }
                    unnamedParameterCount++;
                    totalParameterCount++;
                }

Considers that it found a placeholder for a parameter in the statement, that results in an exception.

Comment From: hkakutalua

@sbrannen can I contribute to fix this issue?

I'll also try to replicate in my machine.

Comment From: snicoll

This is really an edge case of parsing. Even the IDE can't parse that query properly and it's pretty smart about it. If you need to pass a value like that you should really used a parameter (and you're using the right template for that already).