Specify flexible generics nullness in spring-jdbc
This commit leverages flexible generics nullness at method and type level when relevant in spring-jdbc. Due to https://github.com/uber/NullAway/issues/1075, some related `@SuppressWarnings("NullAway")` have been added. JdbcOperations Kotlin extensions have been refined accordingly. Closes gh-34911
This commit is contained in:
parent
2b56b759af
commit
a61b297967
|
@ -110,7 +110,7 @@ public abstract class CollectionUtils {
|
|||
* @since 5.3
|
||||
* @see #newHashMap(int)
|
||||
*/
|
||||
public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(int expectedSize) {
|
||||
public static <K, V extends @Nullable Object> LinkedHashMap<K, V> newLinkedHashMap(int expectedSize) {
|
||||
return new LinkedHashMap<>(computeInitialCapacity(expectedSize), DEFAULT_LOAD_FACTOR);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ import org.springframework.dao.DataAccessException;
|
|||
* @see JdbcTemplate#execute(CallableStatementCreator, CallableStatementCallback)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface CallableStatementCallback<T> {
|
||||
public interface CallableStatementCallback<T extends @Nullable Object> {
|
||||
|
||||
/**
|
||||
* Gets called by {@code JdbcTemplate.execute} with an active JDBC
|
||||
|
@ -75,6 +75,6 @@ public interface CallableStatementCallback<T> {
|
|||
* into a DataAccessException by an SQLExceptionTranslator
|
||||
* @throws DataAccessException in case of custom exceptions
|
||||
*/
|
||||
@Nullable T doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException;
|
||||
T doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException;
|
||||
|
||||
}
|
||||
|
|
|
@ -44,13 +44,13 @@ import org.springframework.util.LinkedCaseInsensitiveMap;
|
|||
* @see JdbcTemplate#queryForList(String)
|
||||
* @see JdbcTemplate#queryForMap(String)
|
||||
*/
|
||||
public class ColumnMapRowMapper implements RowMapper<Map<String, Object>> {
|
||||
public class ColumnMapRowMapper implements RowMapper<Map<String, @Nullable Object>> {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
public Map<String, @Nullable Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int columnCount = rsmd.getColumnCount();
|
||||
Map<String, Object> mapOfColumnValues = createColumnMap(columnCount);
|
||||
Map<String, @Nullable Object> mapOfColumnValues = createColumnMap(columnCount);
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
String column = JdbcUtils.lookupColumnName(rsmd, i);
|
||||
mapOfColumnValues.putIfAbsent(getColumnKey(column), getColumnValue(rs, i));
|
||||
|
@ -66,7 +66,7 @@ public class ColumnMapRowMapper implements RowMapper<Map<String, Object>> {
|
|||
* @return the new Map instance
|
||||
* @see org.springframework.util.LinkedCaseInsensitiveMap
|
||||
*/
|
||||
protected Map<String, Object> createColumnMap(int columnCount) {
|
||||
protected Map<String, @Nullable Object> createColumnMap(int columnCount) {
|
||||
return new LinkedCaseInsensitiveMap<>(columnCount);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ import org.springframework.dao.DataAccessException;
|
|||
* @see JdbcTemplate#update
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionCallback<T> {
|
||||
public interface ConnectionCallback<T extends @Nullable Object> {
|
||||
|
||||
/**
|
||||
* Gets called by {@code JdbcTemplate.execute} with an active JDBC
|
||||
|
@ -65,6 +65,6 @@ public interface ConnectionCallback<T> {
|
|||
* @see JdbcTemplate#queryForObject(String, Class)
|
||||
* @see JdbcTemplate#queryForRowSet(String)
|
||||
*/
|
||||
@Nullable T doInConnection(Connection con) throws SQLException, DataAccessException;
|
||||
T doInConnection(Connection con) throws SQLException, DataAccessException;
|
||||
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public interface JdbcOperations {
|
|||
* @return a result object returned by the action, or {@code null} if none
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T execute(ConnectionCallback<T> action) throws DataAccessException;
|
||||
<T extends @Nullable Object> T execute(ConnectionCallback<T> action) throws DataAccessException;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -87,7 +87,7 @@ public interface JdbcOperations {
|
|||
* @return a result object returned by the action, or {@code null} if none
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T execute(StatementCallback<T> action) throws DataAccessException;
|
||||
<T extends @Nullable Object> T execute(StatementCallback<T> action) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Issue a single SQL execute, typically a DDL statement.
|
||||
|
@ -108,7 +108,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if there is any problem executing the query
|
||||
* @see #query(String, ResultSetExtractor, Object...)
|
||||
*/
|
||||
<T> @Nullable T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
<T extends @Nullable Object> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a query given static SQL, reading the ResultSet on a per-row
|
||||
|
@ -135,7 +135,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if there is any problem executing the query
|
||||
* @see #query(String, RowMapper, Object...)
|
||||
*/
|
||||
<T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
<T extends @Nullable Object> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a query given static SQL, mapping each row to a result object
|
||||
|
@ -151,7 +151,7 @@ public interface JdbcOperations {
|
|||
* @since 5.3
|
||||
* @see #queryForStream(String, RowMapper, Object...)
|
||||
*/
|
||||
<T> Stream<T> queryForStream(String sql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
<T extends @Nullable Object> Stream<T> queryForStream(String sql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a query given static SQL, mapping a single result row to a
|
||||
|
@ -169,7 +169,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if there is any problem executing the query
|
||||
* @see #queryForObject(String, RowMapper, Object...)
|
||||
*/
|
||||
<T> @Nullable T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
<T extends @Nullable Object> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a query for a result object, given static SQL.
|
||||
|
@ -208,7 +208,7 @@ public interface JdbcOperations {
|
|||
* @see #queryForMap(String, Object...)
|
||||
* @see ColumnMapRowMapper
|
||||
*/
|
||||
Map<String, Object> queryForMap(String sql) throws DataAccessException;
|
||||
Map<String, @Nullable Object> queryForMap(String sql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a query for a result list, given static SQL.
|
||||
|
@ -225,7 +225,7 @@ public interface JdbcOperations {
|
|||
* @see #queryForList(String, Class, Object...)
|
||||
* @see SingleColumnRowMapper
|
||||
*/
|
||||
<T> List<T> queryForList(String sql, Class<T> elementType) throws DataAccessException;
|
||||
<T> List<@Nullable T> queryForList(String sql, Class<T> elementType) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a query for a result list, given static SQL.
|
||||
|
@ -241,7 +241,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if there is any problem executing the query
|
||||
* @see #queryForList(String, Object...)
|
||||
*/
|
||||
List<Map<String, Object>> queryForList(String sql) throws DataAccessException;
|
||||
List<Map<String, @Nullable Object>> queryForList(String sql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a query for an SqlRowSet, given static SQL.
|
||||
|
@ -299,7 +299,7 @@ public interface JdbcOperations {
|
|||
* @return a result object returned by the action, or {@code null} if none
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException;
|
||||
<T extends @Nullable Object> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a JDBC data access operation, implemented as callback action
|
||||
|
@ -314,7 +314,7 @@ public interface JdbcOperations {
|
|||
* @return a result object returned by the action, or {@code null} if none
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException;
|
||||
<T extends @Nullable Object> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query using a prepared statement, reading the ResultSet with a ResultSetExtractor.
|
||||
|
@ -326,7 +326,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if there is any problem
|
||||
* @see PreparedStatementCreatorFactory
|
||||
*/
|
||||
<T> @Nullable T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
<T extends @Nullable Object> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query using a prepared statement, reading the ResultSet with a ResultSetExtractor.
|
||||
|
@ -339,7 +339,7 @@ public interface JdbcOperations {
|
|||
* @return an arbitrary result object, as returned by the ResultSetExtractor
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse)
|
||||
<T extends @Nullable Object> T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -354,7 +354,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @see java.sql.Types
|
||||
*/
|
||||
<T> @Nullable T query(String sql, @Nullable Object @Nullable [] args, int[] argTypes, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
<T extends @Nullable Object> T query(String sql, @Nullable Object @Nullable [] args, int[] argTypes, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of arguments
|
||||
|
@ -370,7 +370,7 @@ public interface JdbcOperations {
|
|||
* @deprecated in favor of {@link #query(String, ResultSetExtractor, Object...)}
|
||||
*/
|
||||
@Deprecated(since = "5.3")
|
||||
<T> @Nullable T query(String sql, @Nullable Object @Nullable [] args, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
<T extends @Nullable Object> T query(String sql, @Nullable Object @Nullable [] args, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of arguments
|
||||
|
@ -385,7 +385,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @since 3.0.1
|
||||
*/
|
||||
<T> @Nullable T query(String sql, ResultSetExtractor<T> rse, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
<T extends @Nullable Object> T query(String sql, ResultSetExtractor<T> rse, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query using a prepared statement, reading the ResultSet on a per-row basis
|
||||
|
@ -469,7 +469,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if there is any problem
|
||||
* @see PreparedStatementCreatorFactory
|
||||
*/
|
||||
<T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
<T extends @Nullable Object> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a
|
||||
|
@ -484,7 +484,7 @@ public interface JdbcOperations {
|
|||
* @return the result List, containing mapped objects
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> List<T> query(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper)
|
||||
<T extends @Nullable Object> List<T> query(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -500,7 +500,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @see java.sql.Types
|
||||
*/
|
||||
<T> List<T> query(String sql, @Nullable Object @Nullable [] args, int[] argTypes, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
<T extends @Nullable Object> List<T> query(String sql, @Nullable Object @Nullable [] args, int[] argTypes, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -517,7 +517,7 @@ public interface JdbcOperations {
|
|||
* @deprecated in favor of {@link #query(String, RowMapper, Object...)}
|
||||
*/
|
||||
@Deprecated(since = "5.3")
|
||||
<T> List<T> query(String sql, @Nullable Object @Nullable [] args, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
<T extends @Nullable Object> List<T> query(String sql, @Nullable Object @Nullable [] args, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -533,7 +533,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @since 3.0.1
|
||||
*/
|
||||
<T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
<T extends @Nullable Object> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query using a prepared statement, mapping each row to a result object
|
||||
|
@ -548,7 +548,7 @@ public interface JdbcOperations {
|
|||
* @see PreparedStatementCreatorFactory
|
||||
* @since 5.3
|
||||
*/
|
||||
<T> Stream<T> queryForStream(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
<T extends @Nullable Object> Stream<T> queryForStream(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a
|
||||
|
@ -566,7 +566,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @since 5.3
|
||||
*/
|
||||
<T> Stream<T> queryForStream(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper)
|
||||
<T extends @Nullable Object> Stream<T> queryForStream(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -584,7 +584,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @since 5.3
|
||||
*/
|
||||
<T> Stream<T> queryForStream(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args)
|
||||
<T extends @Nullable Object> Stream<T> queryForStream(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -603,7 +603,7 @@ public interface JdbcOperations {
|
|||
* if the query does not return exactly one row
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> @Nullable T queryForObject(String sql, @Nullable Object @Nullable [] args, int[] argTypes, RowMapper<T> rowMapper)
|
||||
<T extends @Nullable Object> T queryForObject(String sql, @Nullable Object @Nullable [] args, int[] argTypes, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -624,7 +624,7 @@ public interface JdbcOperations {
|
|||
* @deprecated in favor of {@link #queryForObject(String, RowMapper, Object...)}
|
||||
*/
|
||||
@Deprecated(since = "5.3")
|
||||
<T> @Nullable T queryForObject(String sql, @Nullable Object @Nullable [] args, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
<T extends @Nullable Object> T queryForObject(String sql, @Nullable Object @Nullable [] args, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list
|
||||
|
@ -643,7 +643,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @since 3.0.1
|
||||
*/
|
||||
<T> @Nullable T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
<T extends @Nullable Object> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -729,7 +729,7 @@ public interface JdbcOperations {
|
|||
* @see ColumnMapRowMapper
|
||||
* @see java.sql.Types
|
||||
*/
|
||||
Map<String, Object> queryForMap(String sql, @Nullable Object @Nullable [] args, int[] argTypes) throws DataAccessException;
|
||||
Map<String, @Nullable Object> queryForMap(String sql, @Nullable Object @Nullable [] args, int[] argTypes) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -752,7 +752,7 @@ public interface JdbcOperations {
|
|||
* @see #queryForMap(String)
|
||||
* @see ColumnMapRowMapper
|
||||
*/
|
||||
Map<String, Object> queryForMap(String sql, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
Map<String, @Nullable Object> queryForMap(String sql, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -770,7 +770,7 @@ public interface JdbcOperations {
|
|||
* @see #queryForList(String, Class)
|
||||
* @see SingleColumnRowMapper
|
||||
*/
|
||||
<T> List<T> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes, Class<T> elementType)
|
||||
<T> List<@Nullable T> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes, Class<T> elementType)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -792,7 +792,7 @@ public interface JdbcOperations {
|
|||
* @deprecated in favor of {@link #queryForList(String, Class, Object...)}
|
||||
*/
|
||||
@Deprecated(since = "5.3")
|
||||
<T> List<T> queryForList(String sql, @Nullable Object @Nullable [] args, Class<T> elementType) throws DataAccessException;
|
||||
<T> List<@Nullable T> queryForList(String sql, @Nullable Object @Nullable [] args, Class<T> elementType) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -812,7 +812,7 @@ public interface JdbcOperations {
|
|||
* @see #queryForList(String, Class)
|
||||
* @see SingleColumnRowMapper
|
||||
*/
|
||||
<T> List<T> queryForList(String sql, Class<T> elementType, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
<T> List<@Nullable T> queryForList(String sql, Class<T> elementType, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -830,7 +830,7 @@ public interface JdbcOperations {
|
|||
* @see #queryForList(String)
|
||||
* @see java.sql.Types
|
||||
*/
|
||||
List<Map<String, Object>> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes) throws DataAccessException;
|
||||
List<Map<String, @Nullable Object>> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -848,7 +848,7 @@ public interface JdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @see #queryForList(String)
|
||||
*/
|
||||
List<Map<String, Object>> queryForList(String sql, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
List<Map<String, @Nullable Object>> queryForList(String sql, @Nullable Object @Nullable ... args) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -1064,7 +1064,7 @@ public interface JdbcOperations {
|
|||
* @return a result object returned by the action, or {@code null} if none
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T execute(CallableStatementCreator csc, CallableStatementCallback<T> action) throws DataAccessException;
|
||||
<T extends @Nullable Object> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a JDBC data access operation, implemented as callback action
|
||||
|
@ -1079,7 +1079,7 @@ public interface JdbcOperations {
|
|||
* @return a result object returned by the action, or {@code null} if none
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T execute(String callString, CallableStatementCallback<T> action) throws DataAccessException;
|
||||
<T extends @Nullable Object> T execute(String callString, CallableStatementCallback<T> action) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute an SQL call using a CallableStatementCreator to provide SQL and
|
||||
|
@ -1089,7 +1089,7 @@ public interface JdbcOperations {
|
|||
* @return a Map of extracted out parameters
|
||||
* @throws DataAccessException if there is any problem issuing the update
|
||||
*/
|
||||
Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters)
|
||||
Map<String, @Nullable Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters)
|
||||
throws DataAccessException;
|
||||
|
||||
}
|
||||
|
|
|
@ -357,7 +357,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
//-------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T execute(ConnectionCallback<T> action) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T execute(ConnectionCallback<T> action) throws DataAccessException {
|
||||
Assert.notNull(action, "Callback object must not be null");
|
||||
|
||||
Connection con = DataSourceUtils.getConnection(obtainDataSource());
|
||||
|
@ -402,7 +402,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
// Methods dealing with static SQL (java.sql.Statement)
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
private <T> @Nullable T execute(StatementCallback<T> action, boolean closeResources) throws DataAccessException {
|
||||
private <T extends @Nullable Object> T execute(StatementCallback<T> action, boolean closeResources) throws DataAccessException {
|
||||
Assert.notNull(action, "Callback object must not be null");
|
||||
|
||||
Connection con = DataSourceUtils.getConnection(obtainDataSource());
|
||||
|
@ -436,18 +436,19 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T execute(StatementCallback<T> action) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T execute(StatementCallback<T> action) throws DataAccessException {
|
||||
return execute(action, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public void execute(String sql) throws DataAccessException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing SQL statement [" + sql + "]");
|
||||
}
|
||||
|
||||
// Callback to execute the statement.
|
||||
class ExecuteStatementCallback implements StatementCallback<Object>, SqlProvider {
|
||||
class ExecuteStatementCallback implements StatementCallback<@Nullable Object>, SqlProvider {
|
||||
@Override
|
||||
public @Nullable Object doInStatement(Statement stmt) throws SQLException {
|
||||
stmt.execute(sql);
|
||||
|
@ -463,7 +464,8 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T extends @Nullable Object> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
Assert.notNull(sql, "SQL must not be null");
|
||||
Assert.notNull(rse, "ResultSetExtractor must not be null");
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
@ -493,12 +495,13 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public void query(String sql, RowCallbackHandler rch) throws DataAccessException {
|
||||
query(sql, new RowCallbackHandlerResultSetExtractor(rch, this.maxRows));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
public <T extends @Nullable Object> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return result(query(sql, new RowMapperResultSetExtractor<>(rowMapper, 0, this.maxRows)));
|
||||
}
|
||||
|
||||
|
@ -525,12 +528,12 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryForMap(String sql) throws DataAccessException {
|
||||
public Map<String, @Nullable Object> queryForMap(String sql) throws DataAccessException {
|
||||
return result(queryForObject(sql, getColumnMapRowMapper()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
List<T> results = query(sql, rowMapper);
|
||||
return DataAccessUtils.nullableSingleResult(results);
|
||||
}
|
||||
|
@ -541,12 +544,13 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryForList(String sql, Class<T> elementType) throws DataAccessException {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T> List<@Nullable T> queryForList(String sql, Class<T> elementType) throws DataAccessException {
|
||||
return query(sql, getSingleColumnRowMapper(elementType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryForList(String sql) throws DataAccessException {
|
||||
public List<Map<String, @Nullable Object>> queryForList(String sql) throws DataAccessException {
|
||||
return query(sql, getColumnMapRowMapper());
|
||||
}
|
||||
|
||||
|
@ -651,7 +655,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
// Methods dealing with prepared statements
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
private <T> @Nullable T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action, boolean closeResources)
|
||||
private <T extends @Nullable Object> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action, boolean closeResources)
|
||||
throws DataAccessException {
|
||||
|
||||
Assert.notNull(psc, "PreparedStatementCreator must not be null");
|
||||
|
@ -699,14 +703,14 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)
|
||||
public <T extends @Nullable Object> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)
|
||||
throws DataAccessException {
|
||||
|
||||
return execute(psc, action, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException {
|
||||
return execute(new SimplePreparedStatementCreator(sql), action, true);
|
||||
}
|
||||
|
||||
|
@ -747,37 +751,41 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T extends @Nullable Object> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
return query(psc, null, rse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T extends @Nullable Object> T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
return query(new SimplePreparedStatementCreator(sql), pss, rse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T query(String sql, @Nullable Object @Nullable [] args, int[] argTypes, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T query(String sql, @Nullable Object @Nullable [] args, int[] argTypes, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
return query(sql, newArgTypePreparedStatementSetter(args, argTypes), rse);
|
||||
}
|
||||
|
||||
@Deprecated(since = "5.3")
|
||||
@Override
|
||||
public <T> @Nullable T query(String sql, @Nullable Object @Nullable [] args, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T query(String sql, @Nullable Object @Nullable [] args, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
return query(sql, newArgPreparedStatementSetter(args), rse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T query(String sql, ResultSetExtractor<T> rse, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T query(String sql, ResultSetExtractor<T> rse, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
return query(sql, newArgPreparedStatementSetter(args), rse);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException {
|
||||
query(psc, new RowCallbackHandlerResultSetExtractor(rch, this.maxRows));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public void query(String sql, @Nullable PreparedStatementSetter pss, RowCallbackHandler rch) throws DataAccessException {
|
||||
query(sql, pss, new RowCallbackHandlerResultSetExtractor(rch, this.maxRows));
|
||||
}
|
||||
|
@ -799,28 +807,28 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
public <T extends @Nullable Object> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return result(query(psc, new RowMapperResultSetExtractor<>(rowMapper, 0, this.maxRows)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> query(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
public <T extends @Nullable Object> List<T> query(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return result(query(sql, pss, new RowMapperResultSetExtractor<>(rowMapper, 0, this.maxRows)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> query(String sql, @Nullable Object @Nullable [] args, int[] argTypes, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
public <T extends @Nullable Object> List<T> query(String sql, @Nullable Object @Nullable [] args, int[] argTypes, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return result(query(sql, args, argTypes, new RowMapperResultSetExtractor<>(rowMapper, 0, this.maxRows)));
|
||||
}
|
||||
|
||||
@Deprecated(since = "5.3")
|
||||
@Override
|
||||
public <T> List<T> query(String sql, @Nullable Object @Nullable [] args, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
public <T extends @Nullable Object> List<T> query(String sql, @Nullable Object @Nullable [] args, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return result(query(sql, newArgPreparedStatementSetter(args), new RowMapperResultSetExtractor<>(rowMapper, 0, this.maxRows)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
public <T extends @Nullable Object> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
return result(query(sql, newArgPreparedStatementSetter(args), new RowMapperResultSetExtractor<>(rowMapper, 0, this.maxRows)));
|
||||
}
|
||||
|
||||
|
@ -837,7 +845,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @since 5.3
|
||||
*/
|
||||
public <T> Stream<T> queryForStream(PreparedStatementCreator psc, @Nullable PreparedStatementSetter pss,
|
||||
public <T extends @Nullable Object> Stream<T> queryForStream(PreparedStatementCreator psc, @Nullable PreparedStatementSetter pss,
|
||||
RowMapper<T> rowMapper) throws DataAccessException {
|
||||
|
||||
return result(execute(psc, ps -> {
|
||||
|
@ -858,22 +866,22 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> Stream<T> queryForStream(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
public <T extends @Nullable Object> Stream<T> queryForStream(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return queryForStream(psc, null, rowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Stream<T> queryForStream(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
public <T extends @Nullable Object> Stream<T> queryForStream(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return queryForStream(new SimplePreparedStatementCreator(sql), pss, rowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Stream<T> queryForStream(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
public <T extends @Nullable Object> Stream<T> queryForStream(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
return queryForStream(new SimplePreparedStatementCreator(sql), newArgPreparedStatementSetter(args), rowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T queryForObject(String sql, @Nullable Object @Nullable [] args, int[] argTypes, RowMapper<T> rowMapper)
|
||||
public <T extends @Nullable Object> T queryForObject(String sql, @Nullable Object @Nullable [] args, int[] argTypes, RowMapper<T> rowMapper)
|
||||
throws DataAccessException {
|
||||
|
||||
List<T> results = query(sql, args, argTypes, new RowMapperResultSetExtractor<>(rowMapper, 1));
|
||||
|
@ -882,13 +890,13 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
|
||||
@Deprecated(since = "5.3")
|
||||
@Override
|
||||
public <T> @Nullable T queryForObject(String sql,@Nullable Object @Nullable [] args, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T queryForObject(String sql, @Nullable Object @Nullable [] args, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
List<T> results = query(sql, newArgPreparedStatementSetter(args), new RowMapperResultSetExtractor<>(rowMapper, 1));
|
||||
return DataAccessUtils.nullableSingleResult(results);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
List<T> results = query(sql, newArgPreparedStatementSetter(args), new RowMapperResultSetExtractor<>(rowMapper, 1));
|
||||
return DataAccessUtils.nullableSingleResult(results);
|
||||
}
|
||||
|
@ -912,38 +920,41 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryForMap(String sql, @Nullable Object @Nullable [] args, int[] argTypes) throws DataAccessException {
|
||||
public Map<String, @Nullable Object> queryForMap(String sql, @Nullable Object @Nullable [] args, int[] argTypes) throws DataAccessException {
|
||||
return result(queryForObject(sql, args, argTypes, getColumnMapRowMapper()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryForMap(String sql, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
public Map<String, @Nullable Object> queryForMap(String sql, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
return result(queryForObject(sql, getColumnMapRowMapper(), args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes, Class<T> elementType) throws DataAccessException {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T> List<@Nullable T> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes, Class<T> elementType) throws DataAccessException {
|
||||
return query(sql, args, argTypes, getSingleColumnRowMapper(elementType));
|
||||
}
|
||||
|
||||
@Deprecated(since = "5.3")
|
||||
@Override
|
||||
public <T> List<T> queryForList(String sql, @Nullable Object @Nullable [] args, Class<T> elementType) throws DataAccessException {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T> List<@Nullable T> queryForList(String sql, @Nullable Object @Nullable [] args, Class<T> elementType) throws DataAccessException {
|
||||
return query(sql, newArgPreparedStatementSetter(args), getSingleColumnRowMapper(elementType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryForList(String sql, Class<T> elementType, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T> List<@Nullable T> queryForList(String sql, Class<T> elementType, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
return query(sql, newArgPreparedStatementSetter(args), getSingleColumnRowMapper(elementType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes) throws DataAccessException {
|
||||
public List<Map<String, @Nullable Object>> queryForList(String sql, @Nullable Object @Nullable [] args, int[] argTypes) throws DataAccessException {
|
||||
return query(sql, args, argTypes, getColumnMapRowMapper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryForList(String sql, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
public List<Map<String, @Nullable Object>> queryForList(String sql, @Nullable Object @Nullable ... args) throws DataAccessException {
|
||||
return query(sql, newArgPreparedStatementSetter(args), getColumnMapRowMapper());
|
||||
}
|
||||
|
||||
|
@ -1146,7 +1157,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
//-------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T execute(CallableStatementCreator csc, CallableStatementCallback<T> action)
|
||||
public <T extends @Nullable Object> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action)
|
||||
throws DataAccessException {
|
||||
|
||||
Assert.notNull(csc, "CallableStatementCreator must not be null");
|
||||
|
@ -1192,12 +1203,12 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T execute(String callString, CallableStatementCallback<T> action) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T execute(String callString, CallableStatementCallback<T> action) throws DataAccessException {
|
||||
return execute(new SimpleCallableStatementCreator(callString), action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters)
|
||||
public Map<String, @Nullable Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters)
|
||||
throws DataAccessException {
|
||||
|
||||
List<SqlParameter> updateCountParameters = new ArrayList<>();
|
||||
|
@ -1218,14 +1229,14 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
}
|
||||
}
|
||||
|
||||
Map<String, Object> result = execute(csc, cs -> {
|
||||
Map<String, @Nullable Object> result = execute(csc, cs -> {
|
||||
boolean retVal = cs.execute();
|
||||
int updateCount = cs.getUpdateCount();
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("CallableStatement.execute() returned '" + retVal + "'");
|
||||
logger.trace("CallableStatement.getUpdateCount() returned " + updateCount);
|
||||
}
|
||||
Map<String, Object> resultsMap = createResultsMap();
|
||||
Map<String, @Nullable Object> resultsMap = createResultsMap();
|
||||
if (retVal || updateCount != -1) {
|
||||
resultsMap.putAll(extractReturnedResults(cs, updateCountParameters, resultSetParameters, updateCount));
|
||||
}
|
||||
|
@ -1244,11 +1255,11 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
* @param resultSetParameters the parameter list of declared resultSet parameters for the stored procedure
|
||||
* @return a Map that contains returned results
|
||||
*/
|
||||
protected Map<String, Object> extractReturnedResults(CallableStatement cs,
|
||||
protected Map<String, @Nullable Object> extractReturnedResults(CallableStatement cs,
|
||||
@Nullable List<SqlParameter> updateCountParameters, @Nullable List<SqlParameter> resultSetParameters,
|
||||
int updateCount) throws SQLException {
|
||||
|
||||
Map<String, Object> results = new LinkedHashMap<>(4);
|
||||
Map<String, @Nullable Object> results = new LinkedHashMap<>(4);
|
||||
int rsIndex = 0;
|
||||
int updateIndex = 0;
|
||||
boolean moreResults;
|
||||
|
@ -1307,10 +1318,10 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
* @param parameters parameter list for the stored procedure
|
||||
* @return a Map that contains returned results
|
||||
*/
|
||||
protected Map<String, Object> extractOutputParameters(CallableStatement cs, List<SqlParameter> parameters)
|
||||
protected Map<String, @Nullable Object> extractOutputParameters(CallableStatement cs, List<SqlParameter> parameters)
|
||||
throws SQLException {
|
||||
|
||||
Map<String, Object> results = CollectionUtils.newLinkedHashMap(parameters.size());
|
||||
Map<String, @Nullable Object> results = CollectionUtils.newLinkedHashMap(parameters.size());
|
||||
int sqlColIndex = 1;
|
||||
for (SqlParameter param : parameters) {
|
||||
if (param instanceof SqlOutParameter outParam) {
|
||||
|
@ -1353,13 +1364,14 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
* @param param the corresponding stored procedure parameter
|
||||
* @return a Map that contains returned results
|
||||
*/
|
||||
protected Map<String, Object> processResultSet(
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/950
|
||||
protected Map<@Nullable String, @Nullable Object> processResultSet(
|
||||
@Nullable ResultSet rs, ResultSetSupportingSqlParameter param) throws SQLException {
|
||||
|
||||
if (rs != null) {
|
||||
try {
|
||||
if (param.getRowMapper() != null) {
|
||||
RowMapper<?> rowMapper = param.getRowMapper();
|
||||
RowMapper<? extends @Nullable Object> rowMapper = param.getRowMapper();
|
||||
Object data = (new RowMapperResultSetExtractor<>(rowMapper)).extractData(rs);
|
||||
return Collections.singletonMap(param.getName(), data);
|
||||
}
|
||||
|
@ -1391,7 +1403,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
* @return the RowMapper to use
|
||||
* @see ColumnMapRowMapper
|
||||
*/
|
||||
protected RowMapper<Map<String, Object>> getColumnMapRowMapper() {
|
||||
protected RowMapper<Map<String, @Nullable Object>> getColumnMapRowMapper() {
|
||||
return new ColumnMapRowMapper();
|
||||
}
|
||||
|
||||
|
@ -1401,7 +1413,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
* @return the RowMapper to use
|
||||
* @see SingleColumnRowMapper
|
||||
*/
|
||||
protected <T> RowMapper<T> getSingleColumnRowMapper(Class<T> requiredType) {
|
||||
protected <T> RowMapper<@Nullable T> getSingleColumnRowMapper(Class<T> requiredType) {
|
||||
return new SingleColumnRowMapper<>(requiredType);
|
||||
}
|
||||
|
||||
|
@ -1414,7 +1426,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
* @see #setResultsMapCaseInsensitive
|
||||
* @see #isResultsMapCaseInsensitive
|
||||
*/
|
||||
protected Map<String, Object> createResultsMap() {
|
||||
protected Map<String, @Nullable Object> createResultsMap() {
|
||||
if (isResultsMapCaseInsensitive()) {
|
||||
return new LinkedCaseInsensitiveMap<>();
|
||||
}
|
||||
|
@ -1744,7 +1756,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
|||
* <p>Uses a regular ResultSet, so we have to be careful when using it:
|
||||
* We don't use it for navigating since this could lead to unpredictable consequences.
|
||||
*/
|
||||
private static class RowCallbackHandlerResultSetExtractor implements ResultSetExtractor<Object> {
|
||||
private static class RowCallbackHandlerResultSetExtractor implements ResultSetExtractor<@Nullable Object> {
|
||||
|
||||
private final RowCallbackHandler rch;
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ package org.springframework.jdbc.core;
|
|||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Parameterized callback interface used by the {@link JdbcTemplate} class for
|
||||
* batch updates.
|
||||
|
@ -47,6 +49,6 @@ public interface ParameterizedPreparedStatementSetter<T> {
|
|||
* @param argument the object containing the values to be set
|
||||
* @throws SQLException if an SQLException is encountered (i.e. there is no need to catch SQLException)
|
||||
*/
|
||||
void setValues(PreparedStatement ps, T argument) throws SQLException;
|
||||
void setValues(PreparedStatement ps, @Nullable T argument) throws SQLException;
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ import org.springframework.dao.DataAccessException;
|
|||
* @see JdbcTemplate#execute(PreparedStatementCreator, PreparedStatementCallback)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface PreparedStatementCallback<T> {
|
||||
public interface PreparedStatementCallback<T extends @Nullable Object> {
|
||||
|
||||
/**
|
||||
* Gets called by {@code JdbcTemplate.execute} with an active JDBC
|
||||
|
@ -75,6 +75,6 @@ public interface PreparedStatementCallback<T> {
|
|||
* @see JdbcTemplate#queryForObject(String, Class, Object...)
|
||||
* @see JdbcTemplate#queryForList(String, Object...)
|
||||
*/
|
||||
@Nullable T doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException;
|
||||
T doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException;
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ import org.springframework.dao.DataAccessException;
|
|||
* @see org.springframework.jdbc.core.support.AbstractLobStreamingResultSetExtractor
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ResultSetExtractor<T> {
|
||||
public interface ResultSetExtractor<T extends @Nullable Object> {
|
||||
|
||||
/**
|
||||
* Implementations must implement this method to process the entire ResultSet.
|
||||
|
@ -62,6 +62,6 @@ public interface ResultSetExtractor<T> {
|
|||
* values or navigating (that is, there's no need to catch SQLException)
|
||||
* @throws DataAccessException in case of custom exceptions
|
||||
*/
|
||||
@Nullable T extractData(ResultSet rs) throws SQLException, DataAccessException;
|
||||
T extractData(ResultSet rs) throws SQLException, DataAccessException;
|
||||
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ import org.jspecify.annotations.Nullable;
|
|||
* @see org.springframework.jdbc.object.MappingSqlQuery
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface RowMapper<T> {
|
||||
public interface RowMapper<T extends @Nullable Object> {
|
||||
|
||||
/**
|
||||
* Implementations must implement this method to map each row of data in the
|
||||
|
@ -61,6 +61,6 @@ public interface RowMapper<T> {
|
|||
* @throws SQLException if an SQLException is encountered while getting
|
||||
* column values (that is, there's no need to catch SQLException)
|
||||
*/
|
||||
@Nullable T mapRow(ResultSet rs, int rowNum) throws SQLException;
|
||||
T mapRow(ResultSet rs, int rowNum) throws SQLException;
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.sql.SQLException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
@ -59,7 +61,7 @@ import org.springframework.util.Assert;
|
|||
* @see JdbcTemplate
|
||||
* @see org.springframework.jdbc.object.MappingSqlQuery
|
||||
*/
|
||||
public class RowMapperResultSetExtractor<T> implements ResultSetExtractor<List<T>> {
|
||||
public class RowMapperResultSetExtractor<T extends @Nullable Object> implements ResultSetExtractor<List<T>> {
|
||||
|
||||
private final RowMapper<T> rowMapper;
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ import org.springframework.util.NumberUtils;
|
|||
* @see JdbcTemplate#queryForList(String, Class)
|
||||
* @see JdbcTemplate#queryForObject(String, Class)
|
||||
*/
|
||||
public class SingleColumnRowMapper<T> implements RowMapper<T> {
|
||||
public class SingleColumnRowMapper<T> implements RowMapper<@Nullable T> {
|
||||
|
||||
private @Nullable Class<?> requiredType;
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ import org.springframework.dao.DataAccessException;
|
|||
* @see JdbcTemplate#execute(StatementCallback)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface StatementCallback<T> {
|
||||
public interface StatementCallback<T extends @Nullable Object> {
|
||||
|
||||
/**
|
||||
* Gets called by {@code JdbcTemplate.execute} with an active JDBC
|
||||
|
@ -68,6 +68,6 @@ public interface StatementCallback<T> {
|
|||
* @see JdbcTemplate#queryForObject(String, Class)
|
||||
* @see JdbcTemplate#queryForRowSet(String)
|
||||
*/
|
||||
@Nullable T doInStatement(Statement stmt) throws SQLException, DataAccessException;
|
||||
T doInStatement(Statement stmt) throws SQLException, DataAccessException;
|
||||
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @return a result object returned by the action, or {@code null}
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback<T> action)
|
||||
<T extends @Nullable Object> T execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback<T> action)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -94,7 +94,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @return a result object returned by the action, or {@code null}
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T execute(String sql, Map<String, ?> paramMap, PreparedStatementCallback<T> action)
|
||||
<T extends @Nullable Object> T execute(String sql, Map<String, ?> paramMap, PreparedStatementCallback<T> action)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -110,7 +110,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @return a result object returned by the action, or {@code null}
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> @Nullable T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException;
|
||||
<T extends @Nullable Object> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list
|
||||
|
@ -122,7 +122,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @return an arbitrary result object, as returned by the ResultSetExtractor
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> @Nullable T query(String sql, SqlParameterSource paramSource, ResultSetExtractor<T> rse)
|
||||
<T extends @Nullable Object> T query(String sql, SqlParameterSource paramSource, ResultSetExtractor<T> rse)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -136,7 +136,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @return an arbitrary result object, as returned by the ResultSetExtractor
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> @Nullable T query(String sql, Map<String, ?> paramMap, ResultSetExtractor<T> rse)
|
||||
<T extends @Nullable Object> T query(String sql, Map<String, ?> paramMap, ResultSetExtractor<T> rse)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -150,7 +150,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @return an arbitrary result object, as returned by the ResultSetExtractor
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> @Nullable T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
<T extends @Nullable Object> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
|
@ -198,7 +198,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @return the result List, containing mapped objects
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> List<T> query(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
<T extends @Nullable Object> List<T> query(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -212,7 +212,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @return the result List, containing mapped objects
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> List<T> query(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
<T extends @Nullable Object> List<T> query(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -226,7 +226,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @return the result List, containing mapped objects
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
<T extends @Nullable Object> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list
|
||||
|
@ -240,7 +240,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @since 5.3
|
||||
*/
|
||||
<T> Stream<T> queryForStream(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
<T extends @Nullable Object> Stream<T> queryForStream(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -256,7 +256,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @since 5.3
|
||||
*/
|
||||
<T> Stream<T> queryForStream(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
<T extends @Nullable Object> Stream<T> queryForStream(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -272,7 +272,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* if the query does not return exactly one row
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> @Nullable T queryForObject(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
<T extends @Nullable Object> T queryForObject(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -289,7 +289,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* if the query does not return exactly one row
|
||||
* @throws DataAccessException if the query fails
|
||||
*/
|
||||
<T> @Nullable T queryForObject(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
<T extends @Nullable Object> T queryForObject(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -346,7 +346,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForMap(String)
|
||||
* @see org.springframework.jdbc.core.ColumnMapRowMapper
|
||||
*/
|
||||
Map<String, Object> queryForMap(String sql, SqlParameterSource paramSource) throws DataAccessException;
|
||||
Map<String, @Nullable Object> queryForMap(String sql, SqlParameterSource paramSource) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a
|
||||
|
@ -366,7 +366,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForMap(String)
|
||||
* @see org.springframework.jdbc.core.ColumnMapRowMapper
|
||||
*/
|
||||
Map<String, Object> queryForMap(String sql, Map<String, ?> paramMap) throws DataAccessException;
|
||||
Map<String, @Nullable Object> queryForMap(String sql, Map<String, ?> paramMap) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a
|
||||
|
@ -382,7 +382,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String, Class)
|
||||
* @see org.springframework.jdbc.core.SingleColumnRowMapper
|
||||
*/
|
||||
<T> List<T> queryForList(String sql, SqlParameterSource paramSource, Class<T> elementType)
|
||||
<T> List<@Nullable T> queryForList(String sql, SqlParameterSource paramSource, Class<T> elementType)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -400,7 +400,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String, Class)
|
||||
* @see org.springframework.jdbc.core.SingleColumnRowMapper
|
||||
*/
|
||||
<T> List<T> queryForList(String sql, Map<String, ?> paramMap, Class<T> elementType)
|
||||
<T> List<@Nullable T> queryForList(String sql, Map<String, ?> paramMap, Class<T> elementType)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
@ -416,7 +416,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String)
|
||||
*/
|
||||
List<Map<String, Object>> queryForList(String sql, SqlParameterSource paramSource) throws DataAccessException;
|
||||
List<Map<String, @Nullable Object>> queryForList(String sql, SqlParameterSource paramSource) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a
|
||||
|
@ -432,7 +432,7 @@ public interface NamedParameterJdbcOperations {
|
|||
* @throws DataAccessException if the query fails
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String)
|
||||
*/
|
||||
List<Map<String, Object>> queryForList(String sql, Map<String, ?> paramMap) throws DataAccessException;
|
||||
List<Map<String, @Nullable Object>> queryForList(String sql, Map<String, ?> paramMap) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a
|
||||
|
|
|
@ -161,40 +161,40 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
|||
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback<T> action)
|
||||
public <T extends @Nullable Object> T execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback<T> action)
|
||||
throws DataAccessException {
|
||||
|
||||
return getJdbcOperations().execute(getPreparedStatementCreator(sql, paramSource), action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T execute(String sql, Map<String, ?> paramMap, PreparedStatementCallback<T> action)
|
||||
public <T extends @Nullable Object> T execute(String sql, Map<String, ?> paramMap, PreparedStatementCallback<T> action)
|
||||
throws DataAccessException {
|
||||
|
||||
return execute(sql, new MapSqlParameterSource(paramMap), action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException {
|
||||
return execute(sql, EmptySqlParameterSource.INSTANCE, action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T query(String sql, SqlParameterSource paramSource, ResultSetExtractor<T> rse)
|
||||
public <T extends @Nullable Object> T query(String sql, SqlParameterSource paramSource, ResultSetExtractor<T> rse)
|
||||
throws DataAccessException {
|
||||
|
||||
return getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T query(String sql, Map<String, ?> paramMap, ResultSetExtractor<T> rse)
|
||||
public <T extends @Nullable Object> T query(String sql, Map<String, ?> paramMap, ResultSetExtractor<T> rse)
|
||||
throws DataAccessException {
|
||||
|
||||
return query(sql, new MapSqlParameterSource(paramMap), rse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
public <T extends @Nullable Object> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
return query(sql, EmptySqlParameterSource.INSTANCE, rse);
|
||||
}
|
||||
|
||||
|
@ -218,14 +218,14 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> query(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
public <T extends @Nullable Object> List<T> query(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
throws DataAccessException {
|
||||
|
||||
return getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> query(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
public <T extends @Nullable Object> List<T> query(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
throws DataAccessException {
|
||||
|
||||
return query(sql, new MapSqlParameterSource(paramMap), rowMapper);
|
||||
|
@ -237,21 +237,21 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> Stream<T> queryForStream(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
public <T extends @Nullable Object> Stream<T> queryForStream(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
throws DataAccessException {
|
||||
|
||||
return getJdbcOperations().queryForStream(getPreparedStatementCreator(sql, paramSource), rowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Stream<T> queryForStream(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
public <T extends @Nullable Object> Stream<T> queryForStream(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
throws DataAccessException {
|
||||
|
||||
return queryForStream(sql, new MapSqlParameterSource(paramMap), rowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T queryForObject(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
public <T extends @Nullable Object> T queryForObject(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
throws DataAccessException {
|
||||
|
||||
List<T> results = getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rowMapper);
|
||||
|
@ -259,7 +259,7 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> @Nullable T queryForObject(String sql, Map<String, ?> paramMap, RowMapper<T>rowMapper)
|
||||
public <T extends @Nullable Object> T queryForObject(String sql, Map<String, ?> paramMap, RowMapper<T>rowMapper)
|
||||
throws DataAccessException {
|
||||
|
||||
return queryForObject(sql, new MapSqlParameterSource(paramMap), rowMapper);
|
||||
|
@ -280,42 +280,44 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryForMap(String sql, SqlParameterSource paramSource) throws DataAccessException {
|
||||
Map<String, Object> result = queryForObject(sql, paramSource, new ColumnMapRowMapper());
|
||||
public Map<String, @Nullable Object> queryForMap(String sql, SqlParameterSource paramSource) throws DataAccessException {
|
||||
Map<String, @Nullable Object> result = queryForObject(sql, paramSource, new ColumnMapRowMapper());
|
||||
Assert.state(result != null, "No result map");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryForMap(String sql, Map<String, ?> paramMap) throws DataAccessException {
|
||||
Map<String, Object> result = queryForObject(sql, paramMap, new ColumnMapRowMapper());
|
||||
public Map<String, @Nullable Object> queryForMap(String sql, Map<String, ?> paramMap) throws DataAccessException {
|
||||
Map<String, @Nullable Object> result = queryForObject(sql, paramMap, new ColumnMapRowMapper());
|
||||
Assert.state(result != null, "No result map");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryForList(String sql, SqlParameterSource paramSource, Class<T> elementType)
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T> List<@Nullable T> queryForList(String sql, SqlParameterSource paramSource, Class<T> elementType)
|
||||
throws DataAccessException {
|
||||
|
||||
return query(sql, paramSource, new SingleColumnRowMapper<>(elementType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> queryForList(String sql, Map<String, ?> paramMap, Class<T> elementType)
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T> List<@Nullable T> queryForList(String sql, Map<String, ?> paramMap, Class<T> elementType)
|
||||
throws DataAccessException {
|
||||
|
||||
return queryForList(sql, new MapSqlParameterSource(paramMap), elementType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryForList(String sql, SqlParameterSource paramSource)
|
||||
public List<Map<String, @Nullable Object>> queryForList(String sql, SqlParameterSource paramSource)
|
||||
throws DataAccessException {
|
||||
|
||||
return query(sql, paramSource, new ColumnMapRowMapper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryForList(String sql, Map<String, ?> paramMap)
|
||||
public List<Map<String, @Nullable Object>> queryForList(String sql, Map<String, ?> paramMap)
|
||||
throws DataAccessException {
|
||||
|
||||
return queryForList(sql, new MapSqlParameterSource(paramMap));
|
||||
|
|
|
@ -379,7 +379,7 @@ public abstract class AbstractJdbcCall {
|
|||
* @param parameterSource parameter names and values to be used in call
|
||||
* @return a Map of out parameters
|
||||
*/
|
||||
protected Map<String, Object> doExecute(SqlParameterSource parameterSource) {
|
||||
protected Map<String, @Nullable Object> doExecute(SqlParameterSource parameterSource) {
|
||||
checkCompiled();
|
||||
Map<String, Object> params = matchInParameterValuesWithCallParameters(parameterSource);
|
||||
return executeCallInternal(params);
|
||||
|
@ -391,7 +391,7 @@ public abstract class AbstractJdbcCall {
|
|||
* declared for the stored procedure.
|
||||
* @return a Map of out parameters
|
||||
*/
|
||||
protected Map<String, Object> doExecute(Object... args) {
|
||||
protected Map<String, @Nullable Object> doExecute(Object... args) {
|
||||
checkCompiled();
|
||||
Map<String, ?> params = matchInParameterValuesWithCallParameters(args);
|
||||
return executeCallInternal(params);
|
||||
|
@ -402,7 +402,7 @@ public abstract class AbstractJdbcCall {
|
|||
* @param args a Map of parameter name and values
|
||||
* @return a Map of out parameters
|
||||
*/
|
||||
protected Map<String, Object> doExecute(Map<String, ?> args) {
|
||||
protected Map<String, @Nullable Object> doExecute(Map<String, ?> args) {
|
||||
checkCompiled();
|
||||
Map<String, ?> params = matchInParameterValuesWithCallParameters(args);
|
||||
return executeCallInternal(params);
|
||||
|
@ -411,7 +411,7 @@ public abstract class AbstractJdbcCall {
|
|||
/**
|
||||
* Delegate method to perform the actual call processing.
|
||||
*/
|
||||
private Map<String, Object> executeCallInternal(Map<String, ?> args) {
|
||||
private Map<String, @Nullable Object> executeCallInternal(Map<String, ?> args) {
|
||||
CallableStatementCreator csc = getCallableStatementFactory().newCallableStatementCreator(args);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("The following parameters are used for call " + getCallString() + " with " + args);
|
||||
|
|
|
@ -448,6 +448,7 @@ public abstract class AbstractJdbcInsert {
|
|||
/**
|
||||
* Delegate method to execute the insert, generating any number of keys.
|
||||
*/
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
private KeyHolder executeInsertAndReturnKeyHolderInternal(List<?> values) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("The following parameters are used for call " + getInsertString() + " with: " + values);
|
||||
|
@ -496,7 +497,7 @@ public abstract class AbstractJdbcInsert {
|
|||
keyHolder.getKeyList().add(keys);
|
||||
}
|
||||
else {
|
||||
getJdbcTemplate().execute((ConnectionCallback<Object>) con -> {
|
||||
getJdbcTemplate().execute((ConnectionCallback<@Nullable Object>) con -> {
|
||||
// Do the insert
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
|
|
|
@ -239,18 +239,18 @@ final class DefaultJdbcClient implements JdbcClient {
|
|||
new IndexedParamResultQuerySpec());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> MappedQuerySpec<T> query(Class<T> mappedClass) {
|
||||
@SuppressWarnings({"unchecked", "NullAway"}) // See https://github.com/uber/NullAway/issues/1075
|
||||
public <T> MappedQuerySpec<@Nullable T> query(Class<T> mappedClass) {
|
||||
RowMapper<?> rowMapper = rowMapperCache.computeIfAbsent(mappedClass, key ->
|
||||
BeanUtils.isSimpleProperty(mappedClass) ?
|
||||
new SingleColumnRowMapper<>(mappedClass, conversionService) :
|
||||
new SimplePropertyRowMapper<>(mappedClass, conversionService));
|
||||
return query((RowMapper<T>) rowMapper);
|
||||
return query((RowMapper<@Nullable T>) rowMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> MappedQuerySpec<T> query(RowMapper<T> rowMapper) {
|
||||
public <T extends @Nullable Object> MappedQuerySpec<T> query(RowMapper<T> rowMapper) {
|
||||
return (useNamedParams() ?
|
||||
new NamedParamMappedQuerySpec<>(rowMapper) :
|
||||
new IndexedParamMappedQuerySpec<>(rowMapper));
|
||||
|
@ -267,7 +267,7 @@ final class DefaultJdbcClient implements JdbcClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> T query(ResultSetExtractor<T> rse) {
|
||||
public <T extends @Nullable Object> T query(ResultSetExtractor<T> rse) {
|
||||
T result = (useNamedParams() ?
|
||||
this.namedParamOps.query(this.sql, this.namedParamSource, rse) :
|
||||
this.classicOps.query(statementCreatorForIndexedParams(), rse));
|
||||
|
@ -332,17 +332,18 @@ final class DefaultJdbcClient implements JdbcClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> listOfRows() {
|
||||
public List<Map<String, @Nullable Object>> listOfRows() {
|
||||
return classicOps.queryForList(sql, indexedParams.toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> singleRow() {
|
||||
public Map<String, @Nullable Object> singleRow() {
|
||||
return classicOps.queryForMap(sql, indexedParams.toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> singleColumn() {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public List<@Nullable Object> singleColumn() {
|
||||
return classicOps.queryForList(sql, Object.class, indexedParams.toArray());
|
||||
}
|
||||
}
|
||||
|
@ -356,23 +357,25 @@ final class DefaultJdbcClient implements JdbcClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> listOfRows() {
|
||||
public List<Map<String, @Nullable Object>> listOfRows() {
|
||||
return namedParamOps.queryForList(sql, namedParamSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> singleRow() {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public Map<String, @Nullable Object> singleRow() {
|
||||
return namedParamOps.queryForMap(sql, namedParamSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> singleColumn() {
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
public List<@Nullable Object> singleColumn() {
|
||||
return namedParamOps.queryForList(sql, namedParamSource, Object.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class IndexedParamMappedQuerySpec<T> implements MappedQuerySpec<T> {
|
||||
private class IndexedParamMappedQuerySpec<T extends @Nullable Object> implements MappedQuerySpec<T> {
|
||||
|
||||
private final RowMapper<T> rowMapper;
|
||||
|
||||
|
@ -392,7 +395,7 @@ final class DefaultJdbcClient implements JdbcClient {
|
|||
}
|
||||
|
||||
|
||||
private class NamedParamMappedQuerySpec<T> implements MappedQuerySpec<T> {
|
||||
private class NamedParamMappedQuerySpec<T extends @Nullable Object> implements MappedQuerySpec<T> {
|
||||
|
||||
private final RowMapper<T> rowMapper;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
|
@ -286,7 +287,7 @@ public interface JdbcClient {
|
|||
* @see org.springframework.jdbc.core.SingleColumnRowMapper
|
||||
* @see org.springframework.jdbc.core.SimplePropertyRowMapper
|
||||
*/
|
||||
<T> MappedQuerySpec<T> query(Class<T> mappedClass);
|
||||
<T> MappedQuerySpec<@Nullable T> query(Class<T> mappedClass);
|
||||
|
||||
/**
|
||||
* Proceed towards execution of a mapped query, with several options
|
||||
|
@ -295,7 +296,7 @@ public interface JdbcClient {
|
|||
* @return the mapped query specification
|
||||
* @see java.sql.PreparedStatement#executeQuery()
|
||||
*/
|
||||
<T> MappedQuerySpec<T> query(RowMapper<T> rowMapper);
|
||||
<T extends @Nullable Object> MappedQuerySpec<T> query(RowMapper<T> rowMapper);
|
||||
|
||||
/**
|
||||
* Execute a query with the provided SQL statement,
|
||||
|
@ -312,7 +313,7 @@ public interface JdbcClient {
|
|||
* @return the value returned by the ResultSetExtractor
|
||||
* @see java.sql.PreparedStatement#executeQuery()
|
||||
*/
|
||||
<T> T query(ResultSetExtractor<T> rse);
|
||||
<T extends @Nullable Object> T query(ResultSetExtractor<T> rse);
|
||||
|
||||
/**
|
||||
* Execute the provided SQL statement as an update.
|
||||
|
@ -365,14 +366,14 @@ public interface JdbcClient {
|
|||
* with each result row represented as a map of
|
||||
* case-insensitive column names to column values
|
||||
*/
|
||||
List<Map<String, Object>> listOfRows();
|
||||
List<Map<String, @Nullable Object>> listOfRows();
|
||||
|
||||
/**
|
||||
* Retrieve a single row result.
|
||||
* @return the result row represented as a map of
|
||||
* case-insensitive column names to column values
|
||||
*/
|
||||
Map<String, Object> singleRow();
|
||||
Map<String, @Nullable Object> singleRow();
|
||||
|
||||
/**
|
||||
* Retrieve a single column result,
|
||||
|
@ -380,7 +381,7 @@ public interface JdbcClient {
|
|||
* @return a (potentially empty) list of rows, with each
|
||||
* row represented as its single column value
|
||||
*/
|
||||
List<Object> singleColumn();
|
||||
List<@Nullable Object> singleColumn();
|
||||
|
||||
/**
|
||||
* Retrieve a single value result.
|
||||
|
@ -390,6 +391,7 @@ public interface JdbcClient {
|
|||
* @see #optionalValue()
|
||||
* @see DataAccessUtils#requiredSingleResult(Collection)
|
||||
*/
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
default Object singleValue() {
|
||||
return DataAccessUtils.requiredSingleResult(singleColumn());
|
||||
}
|
||||
|
@ -401,6 +403,7 @@ public interface JdbcClient {
|
|||
* @see #singleValue()
|
||||
* @see DataAccessUtils#optionalResult(Collection)
|
||||
*/
|
||||
@SuppressWarnings("NullAway") // See https://github.com/uber/NullAway/issues/1075
|
||||
default Optional<Object> optionalValue() {
|
||||
return DataAccessUtils.optionalResult(singleColumn());
|
||||
}
|
||||
|
@ -412,7 +415,7 @@ public interface JdbcClient {
|
|||
*
|
||||
* @param <T> the RowMapper-declared result type
|
||||
*/
|
||||
interface MappedQuerySpec<T> {
|
||||
interface MappedQuerySpec<T extends @Nullable Object> {
|
||||
|
||||
/**
|
||||
* Retrieve the result as a lazily resolved stream of mapped objects,
|
||||
|
@ -447,7 +450,7 @@ public interface JdbcClient {
|
|||
* @see #optional()
|
||||
* @see DataAccessUtils#requiredSingleResult(Collection)
|
||||
*/
|
||||
default T single() {
|
||||
default @NonNull T single() {
|
||||
return DataAccessUtils.requiredSingleResult(list());
|
||||
}
|
||||
|
||||
|
@ -457,7 +460,7 @@ public interface JdbcClient {
|
|||
* @see #single()
|
||||
* @see DataAccessUtils#optionalResult(Collection)
|
||||
*/
|
||||
default Optional<T> optional() {
|
||||
default Optional<@NonNull T> optional() {
|
||||
return DataAccessUtils.optionalResult(list());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,17 +186,17 @@ public class SimpleJdbcCall extends AbstractJdbcCall implements SimpleJdbcCallOp
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> execute(Object... args) {
|
||||
public Map<String, @Nullable Object> execute(Object... args) {
|
||||
return doExecute(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> execute(Map<String, ?> args) {
|
||||
public Map<String, @Nullable Object> execute(Map<String, ?> args) {
|
||||
return doExecute(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> execute(SqlParameterSource parameterSource) {
|
||||
public Map<String, @Nullable Object> execute(SqlParameterSource parameterSource) {
|
||||
return doExecute(parameterSource);
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ public interface SimpleJdbcCallOperations {
|
|||
* the stored procedure.
|
||||
* @return a Map of output params
|
||||
*/
|
||||
Map<String, Object> execute(Object... args);
|
||||
Map<String, @Nullable Object> execute(Object... args);
|
||||
|
||||
/**
|
||||
* Execute the stored procedure and return a map of output params, keyed by name
|
||||
|
@ -182,7 +182,7 @@ public interface SimpleJdbcCallOperations {
|
|||
* @param args a Map containing the parameter values to be used in the call
|
||||
* @return a Map of output params
|
||||
*/
|
||||
Map<String, Object> execute(Map<String, ?> args);
|
||||
Map<String, @Nullable Object> execute(Map<String, ?> args);
|
||||
|
||||
/**
|
||||
* Execute the stored procedure and return a map of output params, keyed by name
|
||||
|
@ -190,6 +190,6 @@ public interface SimpleJdbcCallOperations {
|
|||
* @param args the SqlParameterSource containing the parameter values to be used in the call
|
||||
* @return a Map of output params
|
||||
*/
|
||||
Map<String, Object> execute(SqlParameterSource args);
|
||||
Map<String, @Nullable Object> execute(SqlParameterSource args);
|
||||
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ import org.springframework.jdbc.core.ResultSetExtractor;
|
|||
* in favor of {@link ResultSet#getBinaryStream}/{@link ResultSet#getCharacterStream} usage
|
||||
*/
|
||||
@Deprecated(since = "6.2")
|
||||
public abstract class AbstractLobStreamingResultSetExtractor<T> implements ResultSetExtractor<T> {
|
||||
public abstract class AbstractLobStreamingResultSetExtractor<T> implements ResultSetExtractor<@Nullable T> {
|
||||
|
||||
/**
|
||||
* Delegates to handleNoRowFound, handleMultipleRowsFound and streamData,
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.springframework.util.Assert;
|
|||
* @see #setRowMapper
|
||||
* @see #setRowMapperClass
|
||||
*/
|
||||
public class GenericSqlQuery<T> extends SqlQuery<T> {
|
||||
public class GenericSqlQuery<T extends @Nullable Object> extends SqlQuery<T> {
|
||||
|
||||
private @Nullable RowMapper<T> rowMapper;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.jspecify.annotations.Nullable;
|
|||
* @param <T> the result type
|
||||
* @see MappingSqlQueryWithParameters
|
||||
*/
|
||||
public abstract class MappingSqlQuery<T> extends MappingSqlQueryWithParameters<T> {
|
||||
public abstract class MappingSqlQuery<T extends @Nullable Object> extends MappingSqlQueryWithParameters<T> {
|
||||
|
||||
/**
|
||||
* Constructor that allows use as a JavaBean.
|
||||
|
@ -63,7 +63,7 @@ public abstract class MappingSqlQuery<T> extends MappingSqlQueryWithParameters<T
|
|||
* @see #mapRow(ResultSet, int)
|
||||
*/
|
||||
@Override
|
||||
protected final @Nullable T mapRow(ResultSet rs, int rowNum, @Nullable Object @Nullable [] parameters, @Nullable Map<?, ?> context)
|
||||
protected final T mapRow(ResultSet rs, int rowNum, @Nullable Object @Nullable [] parameters, @Nullable Map<?, ?> context)
|
||||
throws SQLException {
|
||||
|
||||
return mapRow(rs, rowNum);
|
||||
|
@ -82,6 +82,6 @@ public abstract class MappingSqlQuery<T> extends MappingSqlQueryWithParameters<T
|
|||
* Subclasses can simply not catch SQLExceptions, relying on the
|
||||
* framework to clean up.
|
||||
*/
|
||||
protected abstract @Nullable T mapRow(ResultSet rs, int rowNum) throws SQLException;
|
||||
protected abstract T mapRow(ResultSet rs, int rowNum) throws SQLException;
|
||||
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ import org.springframework.jdbc.core.RowMapper;
|
|||
* @see org.springframework.jdbc.object.MappingSqlQuery
|
||||
* @see org.springframework.jdbc.object.SqlQuery
|
||||
*/
|
||||
public abstract class MappingSqlQueryWithParameters<T> extends SqlQuery<T> {
|
||||
public abstract class MappingSqlQueryWithParameters<T extends @Nullable Object> extends SqlQuery<T> {
|
||||
|
||||
/**
|
||||
* Constructor to allow use as a JavaBean.
|
||||
|
@ -93,7 +93,7 @@ public abstract class MappingSqlQueryWithParameters<T> extends SqlQuery<T> {
|
|||
* Subclasses can simply not catch SQLExceptions, relying on the
|
||||
* framework to clean up.
|
||||
*/
|
||||
protected abstract @Nullable T mapRow(ResultSet rs, int rowNum, @Nullable Object @Nullable [] parameters, @Nullable Map<?, ?> context)
|
||||
protected abstract T mapRow(ResultSet rs, int rowNum, @Nullable Object @Nullable [] parameters, @Nullable Map<?, ?> context)
|
||||
throws SQLException;
|
||||
|
||||
|
||||
|
@ -116,7 +116,7 @@ public abstract class MappingSqlQueryWithParameters<T> extends SqlQuery<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public @Nullable T mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
return MappingSqlQueryWithParameters.this.mapRow(rs, rowNum, this.params, this.context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ import org.springframework.jdbc.core.SingleColumnRowMapper;
|
|||
* @param <T> the result type
|
||||
* @see StoredProcedure
|
||||
*/
|
||||
public class SqlFunction<T> extends MappingSqlQuery<T> {
|
||||
public class SqlFunction<T> extends MappingSqlQuery<@Nullable T> {
|
||||
|
||||
private final SingleColumnRowMapper<T> rowMapper = new SingleColumnRowMapper<>();
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ import org.springframework.jdbc.core.namedparam.ParsedSql;
|
|||
* @param <T> the result type
|
||||
* @see SqlUpdate
|
||||
*/
|
||||
public abstract class SqlQuery<T> extends SqlOperation {
|
||||
public abstract class SqlQuery<T extends @Nullable Object> extends SqlOperation {
|
||||
|
||||
/**
|
||||
* Constructor to allow use as a JavaBean.
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.util.Map;
|
|||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
@ -109,8 +111,8 @@ public abstract class StoredProcedure extends SqlCall {
|
|||
* Output parameters will appear here, with their values after the stored procedure
|
||||
* has been called.
|
||||
*/
|
||||
public Map<String, Object> execute(Object... inParams) {
|
||||
Map<String, Object> paramsToUse = new HashMap<>();
|
||||
public Map<String, @Nullable Object> execute(Object... inParams) {
|
||||
Map<String, @Nullable Object> paramsToUse = new HashMap<>();
|
||||
validateParameters(inParams);
|
||||
int i = 0;
|
||||
for (SqlParameter sqlParameter : getDeclaredParameters()) {
|
||||
|
@ -135,7 +137,7 @@ public abstract class StoredProcedure extends SqlCall {
|
|||
* Output parameters will appear here, with their values after the
|
||||
* stored procedure has been called.
|
||||
*/
|
||||
public Map<String, Object> execute(Map<String, ?> inParams) throws DataAccessException {
|
||||
public Map<String, @Nullable Object> execute(Map<String, ?> inParams) throws DataAccessException {
|
||||
validateParameters(inParams.values().toArray());
|
||||
return getJdbcTemplate().call(newCallableStatementCreator(inParams), getDeclaredParameters());
|
||||
}
|
||||
|
@ -156,7 +158,7 @@ public abstract class StoredProcedure extends SqlCall {
|
|||
* Output parameters will appear here, with their values after the
|
||||
* stored procedure has been called.
|
||||
*/
|
||||
public Map<String, Object> execute(ParameterMapper inParamMapper) throws DataAccessException {
|
||||
public Map<String, @Nullable Object> execute(ParameterMapper inParamMapper) throws DataAccessException {
|
||||
checkCompiled();
|
||||
return getJdbcTemplate().call(newCallableStatementCreator(inParamMapper), getDeclaredParameters());
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ package org.springframework.jdbc.support;
|
|||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A callback interface used by the JdbcUtils class. Implementations of this
|
||||
* interface perform the actual work of extracting database meta-data, but
|
||||
|
@ -31,7 +33,7 @@ import java.sql.SQLException;
|
|||
* @see JdbcUtils#extractDatabaseMetaData(javax.sql.DataSource, DatabaseMetaDataCallback)
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DatabaseMetaDataCallback<T> {
|
||||
public interface DatabaseMetaDataCallback<T extends @Nullable Object> {
|
||||
|
||||
/**
|
||||
* Implementations must implement this method to process the meta-data
|
||||
|
|
|
@ -321,7 +321,7 @@ public abstract class JdbcUtils {
|
|||
* @throws MetaDataAccessException if meta-data access failed
|
||||
* @see java.sql.DatabaseMetaData
|
||||
*/
|
||||
public static <T> T extractDatabaseMetaData(DataSource dataSource, DatabaseMetaDataCallback<T> action)
|
||||
public static <T extends @Nullable Object> T extractDatabaseMetaData(DataSource dataSource, DatabaseMetaDataCallback<T> action)
|
||||
throws MetaDataAccessException {
|
||||
|
||||
Connection con = null;
|
||||
|
|
|
@ -35,7 +35,7 @@ inline fun <reified T> JdbcOperations.queryForObject(sql: String): T =
|
|||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T> JdbcOperations.queryForObject(sql: String, vararg args: Any, crossinline function: (ResultSet, Int) -> T): T =
|
||||
queryForObject(sql, { resultSet, i -> function(resultSet, i) }, *args) as T
|
||||
queryForObject(sql, { resultSet, i -> function(resultSet, i) }, *args)
|
||||
|
||||
/**
|
||||
* Extension for [JdbcOperations.queryForObject] providing a
|
||||
|
@ -44,7 +44,7 @@ inline fun <reified T> JdbcOperations.queryForObject(sql: String, vararg args: A
|
|||
* @author Mario Arias
|
||||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T> JdbcOperations.queryForObject(sql: String, args: Array<out Any>, argTypes: IntArray): T? =
|
||||
inline fun <reified T> JdbcOperations.queryForObject(sql: String, args: Array<out Any>, argTypes: IntArray): T =
|
||||
queryForObject(sql, args, argTypes, T::class.java as Class<*>) as T
|
||||
|
||||
/**
|
||||
|
@ -54,7 +54,7 @@ inline fun <reified T> JdbcOperations.queryForObject(sql: String, args: Array<ou
|
|||
* @author Mario Arias
|
||||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T> JdbcOperations.queryForObject(sql: String, args: Array<out Any>): T? =
|
||||
inline fun <reified T> JdbcOperations.queryForObject(sql: String, args: Array<out Any>): T =
|
||||
queryForObject(sql, T::class.java as Class<*>, args) as T
|
||||
|
||||
/**
|
||||
|
@ -63,8 +63,9 @@ inline fun <reified T> JdbcOperations.queryForObject(sql: String, args: Array<ou
|
|||
* @author Mario Arias
|
||||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T : Any> JdbcOperations.queryForList(sql: String): List<T> =
|
||||
queryForList(sql, T::class.java)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
inline fun <reified T> JdbcOperations.queryForList(sql: String): List<T> =
|
||||
queryForList(sql, T::class.java) as List<T>
|
||||
|
||||
/**
|
||||
* Extension for [JdbcOperations.queryForList] providing a
|
||||
|
@ -73,9 +74,10 @@ inline fun <reified T : Any> JdbcOperations.queryForList(sql: String): List<T> =
|
|||
* @author Mario Arias
|
||||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T : Any> JdbcOperations.queryForList(sql: String, args: Array<out Any>,
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
inline fun <reified T> JdbcOperations.queryForList(sql: String, args: Array<out Any>,
|
||||
argTypes: IntArray): List<T> =
|
||||
queryForList(sql, args, argTypes, T::class.java)
|
||||
queryForList(sql, args, argTypes, T::class.java) as List<T>
|
||||
|
||||
/**
|
||||
* Extension for [JdbcOperations.queryForList] providing a
|
||||
|
@ -84,8 +86,9 @@ inline fun <reified T : Any> JdbcOperations.queryForList(sql: String, args: Arra
|
|||
* @author Mario Arias
|
||||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T : Any> JdbcOperations.queryForList(sql: String, args: Array<out Any>): List<T> =
|
||||
queryForList(sql, T::class.java, args)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
inline fun <reified T> JdbcOperations.queryForList(sql: String, args: Array<out Any>): List<T> =
|
||||
queryForList(sql, T::class.java, args) as List<T>
|
||||
|
||||
|
||||
/**
|
||||
|
@ -95,9 +98,9 @@ inline fun <reified T : Any> JdbcOperations.queryForList(sql: String, args: Arra
|
|||
* @author Mario Arias
|
||||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T> JdbcOperations.query(sql: String, vararg args: Any,
|
||||
crossinline function: (ResultSet) -> T): T =
|
||||
query(sql, ResultSetExtractor { function(it) }, *args) as T
|
||||
fun <T> JdbcOperations.query(sql: String, vararg args: Any,
|
||||
function: (ResultSet) -> T): T =
|
||||
query(sql, ResultSetExtractor { function(it) }, *args)
|
||||
|
||||
/**
|
||||
* Extension for [JdbcOperations.query] providing a RowCallbackHandler-like function
|
||||
|
|
|
@ -43,6 +43,13 @@ class JdbcOperationsExtensionsTests {
|
|||
verify { template.queryForObject(sql, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForObject with nullable reified type parameters`() {
|
||||
every { template.queryForObject(sql, any<Class<Int>>()) } returns null
|
||||
assertThat(template.queryForObject<Int?>(sql)).isNull()
|
||||
verify { template.queryForObject(sql, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForObject with RowMapper-like function`() {
|
||||
every { template.queryForObject(sql, any<RowMapper<Int>>(), any<Int>()) } returns 2
|
||||
|
@ -52,9 +59,9 @@ class JdbcOperationsExtensionsTests {
|
|||
|
||||
@Test // gh-22682
|
||||
fun `queryForObject with nullable RowMapper-like function`() {
|
||||
every { template.queryForObject(sql, any<RowMapper<Int>>(), 3) } returns null
|
||||
every { template.queryForObject(sql, any<RowMapper<Int?>>(), 3) } returns null
|
||||
assertThat(template.queryForObject<Int?>(sql, 3) { _, _ -> null }).isNull()
|
||||
verify { template.queryForObject(eq(sql), any<RowMapper<Int>>(), eq(3)) }
|
||||
verify { template.queryForObject(eq(sql), any<RowMapper<Int?>>(), eq(3)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -66,6 +73,15 @@ class JdbcOperationsExtensionsTests {
|
|||
verify { template.queryForObject(sql, args, argTypes, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForObject with nullable reified type parameters and argTypes`() {
|
||||
val args = arrayOf(3)
|
||||
val argTypes = intArrayOf(JDBCType.INTEGER.vendorTypeNumber)
|
||||
every { template.queryForObject(sql, args, argTypes, any<Class<Int>>()) } returns null
|
||||
assertThat(template.queryForObject<Int?>(sql, args, argTypes)).isNull()
|
||||
verify { template.queryForObject(sql, args, argTypes, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForObject with reified type parameters and args`() {
|
||||
val args = arrayOf(3, 4)
|
||||
|
@ -74,6 +90,14 @@ class JdbcOperationsExtensionsTests {
|
|||
verify { template.queryForObject(sql, any<Class<Int>>(), args) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForObject with nullable reified type parameters and args`() {
|
||||
val args = arrayOf(3, 4)
|
||||
every { template.queryForObject(sql, any<Class<Int>>(), args) } returns null
|
||||
assertThat(template.queryForObject<Int?>(sql, args)).isNull()
|
||||
verify { template.queryForObject(sql, any<Class<Int>>(), args) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForList with reified type parameters`() {
|
||||
val list = listOf(1, 2, 3)
|
||||
|
@ -82,6 +106,14 @@ class JdbcOperationsExtensionsTests {
|
|||
verify { template.queryForList(sql, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForList with nullable reified type parameters`() {
|
||||
val list = listOf(1, null, 3)
|
||||
every { template.queryForList(sql, any<Class<Int>>()) } returns list
|
||||
assertThat(template.queryForList<Int?>(sql)).isEqualTo(list)
|
||||
verify { template.queryForList(sql, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForList with reified type parameters and argTypes`() {
|
||||
val list = listOf(1, 2, 3)
|
||||
|
@ -92,6 +124,16 @@ class JdbcOperationsExtensionsTests {
|
|||
verify { template.queryForList(sql, args, argTypes, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForList with nullable reified type parameters and argTypes`() {
|
||||
val list = listOf(1, null, 3)
|
||||
val args = arrayOf(3)
|
||||
val argTypes = intArrayOf(JDBCType.INTEGER.vendorTypeNumber)
|
||||
every { template.queryForList(sql, args, argTypes, any<Class<Int>>()) } returns list
|
||||
assertThat(template.queryForList<Int?>(sql, args, argTypes)).isEqualTo(list)
|
||||
verify { template.queryForList(sql, args, argTypes, any<Class<Int>>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForList with reified type parameters and args`() {
|
||||
val list = listOf(1, 2, 3)
|
||||
|
@ -101,6 +143,15 @@ class JdbcOperationsExtensionsTests {
|
|||
verify { template.queryForList(sql, any<Class<Int>>(), args) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `queryForList with nullable reified type parameters and args`() {
|
||||
val list = listOf(1, null, 3)
|
||||
val args = arrayOf(3, 4)
|
||||
every { template.queryForList(sql, any<Class<Int>>(), args) } returns list
|
||||
template.queryForList<Int?>(sql, args)
|
||||
verify { template.queryForList(sql, any<Class<Int>>(), args) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `query with ResultSetExtractor-like function`() {
|
||||
every { template.query(eq(sql), any<ResultSetExtractor<Int>>(), eq(3)) } returns 2
|
||||
|
@ -113,12 +164,11 @@ class JdbcOperationsExtensionsTests {
|
|||
|
||||
@Test // gh-22682
|
||||
fun `query with nullable ResultSetExtractor-like function`() {
|
||||
every { template.query(eq(sql), any<ResultSetExtractor<Int>>(), eq(3)) } returns null
|
||||
every { template.query(eq(sql), any<ResultSetExtractor<Int?>>(), eq(3)) } returns null
|
||||
assertThat(template.query<Int?>(sql, 3) { _ -> null }).isNull()
|
||||
verify { template.query(eq(sql), any<ResultSetExtractor<Int>>(), eq(3)) }
|
||||
verify { template.query(eq(sql), any<ResultSetExtractor<Int?>>(), eq(3)) }
|
||||
}
|
||||
|
||||
@Suppress("RemoveExplicitTypeArguments")
|
||||
@Test
|
||||
fun `query with RowCallbackHandler-like function`() {
|
||||
every { template.query(sql, ofType<RowCallbackHandler>(), 3) } returns Unit
|
||||
|
@ -131,11 +181,21 @@ class JdbcOperationsExtensionsTests {
|
|||
@Test
|
||||
fun `query with RowMapper-like function`() {
|
||||
val list = mutableListOf(1, 2, 3)
|
||||
every { template.query(sql, ofType<RowMapper<*>>(), 3) } returns list
|
||||
every { template.query(sql, ofType<RowMapper<Int>>(), 3) } returns list
|
||||
assertThat(template.query(sql, 3) { rs, _ ->
|
||||
rs.getInt(1)
|
||||
}).isEqualTo(list)
|
||||
verify { template.query(sql, ofType<RowMapper<*>>(), 3) }
|
||||
verify { template.query(sql, ofType<RowMapper<Int>>(), 3) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `query with nullable RowMapper-like function`() {
|
||||
val list = mutableListOf(1, null, 3)
|
||||
every { template.query(sql, ofType<RowMapper<Int?>>(), 3) } returns list
|
||||
assertThat(template.query(sql, 3) { rs, _ ->
|
||||
rs.getInt(1)
|
||||
}).isEqualTo(list)
|
||||
verify { template.query(sql, ofType<RowMapper<Int?>>(), 3) }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
@ -115,7 +116,7 @@ public abstract class DataAccessUtils {
|
|||
* element has been found in the given Collection
|
||||
* @since 6.1
|
||||
*/
|
||||
public static <T> Optional<T> optionalResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
|
||||
public static <T extends @Nullable Object> Optional<@NonNull T> optionalResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
|
||||
return Optional.ofNullable(singleResult(results));
|
||||
}
|
||||
|
||||
|
@ -158,7 +159,7 @@ public abstract class DataAccessUtils {
|
|||
* @throws EmptyResultDataAccessException if no element at all
|
||||
* has been found in the given Collection
|
||||
*/
|
||||
public static <T> T requiredSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
|
||||
public static <T extends @Nullable Object> @NonNull T requiredSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
|
||||
if (CollectionUtils.isEmpty(results)) {
|
||||
throw new EmptyResultDataAccessException(1);
|
||||
}
|
||||
|
@ -184,7 +185,7 @@ public abstract class DataAccessUtils {
|
|||
* has been found in the given Collection
|
||||
* @since 5.0.2
|
||||
*/
|
||||
public static <T> @Nullable T nullableSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
|
||||
public static <T extends @Nullable Object> T nullableSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
|
||||
// This is identical to the requiredSingleResult implementation but differs in the
|
||||
// semantics of the incoming Collection (which we currently can't formally express)
|
||||
if (CollectionUtils.isEmpty(results)) {
|
||||
|
|
Loading…
Reference in New Issue