JdbcTemplate consistently exposes first value of equally named columns
Issue: SPR-16578
This commit is contained in:
parent
b790bd1fd6
commit
7bce7504c7
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -52,13 +52,12 @@ public class ColumnMapRowMapper implements RowMapper<Map<String, Object>> {
|
|||
public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int columnCount = rsmd.getColumnCount();
|
||||
Map<String, Object> mapOfColValues = createColumnMap(columnCount);
|
||||
Map<String, Object> mapOfColumnValues = createColumnMap(columnCount);
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));
|
||||
Object obj = getColumnValue(rs, i);
|
||||
mapOfColValues.put(key, obj);
|
||||
String column = JdbcUtils.lookupColumnName(rsmd, i);
|
||||
mapOfColumnValues.putIfAbsent(getColumnKey(column), getColumnValue(rs, i));
|
||||
}
|
||||
return mapOfColValues;
|
||||
return mapOfColumnValues;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -253,7 +253,7 @@ public class TableMetaDataContext {
|
|||
for (Map.Entry<String, ?> entry : inParameters.entrySet()) {
|
||||
if (column.equalsIgnoreCase(entry.getKey())) {
|
||||
value = entry.getValue();
|
||||
// TODO: break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,14 @@ import java.sql.Connection;
|
|||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -704,10 +706,10 @@ public class JdbcTemplateTests {
|
|||
@Test
|
||||
public void testBatchUpdateWithListOfObjectArrays() throws Exception {
|
||||
final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
|
||||
final List<Object[]> ids = new ArrayList<>();
|
||||
final List<Object[]> ids = new ArrayList<>(2);
|
||||
ids.add(new Object[] {100});
|
||||
ids.add(new Object[] {200});
|
||||
final int[] rowsAffected = new int[] { 1, 2 };
|
||||
final int[] rowsAffected = new int[] {1, 2};
|
||||
|
||||
given(this.preparedStatement.executeBatch()).willReturn(rowsAffected);
|
||||
mockDatabaseMetaData(true);
|
||||
|
@ -730,11 +732,11 @@ public class JdbcTemplateTests {
|
|||
@Test
|
||||
public void testBatchUpdateWithListOfObjectArraysPlusTypeInfo() throws Exception {
|
||||
final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
|
||||
final List<Object[]> ids = new ArrayList<>();
|
||||
final List<Object[]> ids = new ArrayList<>(2);
|
||||
ids.add(new Object[] {100});
|
||||
ids.add(new Object[] {200});
|
||||
final int[] sqlTypes = new int[] {Types.NUMERIC};
|
||||
final int[] rowsAffected = new int[] { 1, 2 };
|
||||
final int[] rowsAffected = new int[] {1, 2};
|
||||
|
||||
given(this.preparedStatement.executeBatch()).willReturn(rowsAffected);
|
||||
mockDatabaseMetaData(true);
|
||||
|
@ -1070,14 +1072,13 @@ public class JdbcTemplateTests {
|
|||
given(this.callableStatement.execute()).willReturn(true);
|
||||
given(this.callableStatement.getUpdateCount()).willReturn(-1);
|
||||
|
||||
List<SqlParameter> params = new ArrayList<>();
|
||||
params.add(new SqlReturnResultSet("", (RowCallbackHandler) rs -> {
|
||||
SqlParameter param = new SqlReturnResultSet("", (RowCallbackHandler) rs -> {
|
||||
throw new InvalidDataAccessApiUsageException("");
|
||||
}));
|
||||
});
|
||||
|
||||
this.thrown.expect(InvalidDataAccessApiUsageException.class);
|
||||
try {
|
||||
this.template.call(conn -> conn.prepareCall("my query"), params);
|
||||
this.template.call(conn -> conn.prepareCall("my query"), Collections.singletonList(param));
|
||||
}
|
||||
finally {
|
||||
verify(this.resultSet).close();
|
||||
|
@ -1099,10 +1100,8 @@ public class JdbcTemplateTests {
|
|||
assertTrue("now it should have been set to case insensitive",
|
||||
this.template.isResultsMapCaseInsensitive());
|
||||
|
||||
List<SqlParameter> params = new ArrayList<>();
|
||||
params.add(new SqlOutParameter("a", 12));
|
||||
|
||||
Map<String, Object> out = this.template.call(conn -> conn.prepareCall("my query"), params);
|
||||
Map<String, Object> out = this.template.call(
|
||||
conn -> conn.prepareCall("my query"), Collections.singletonList(new SqlOutParameter("a", 12)));
|
||||
|
||||
assertThat(out, instanceOf(LinkedCaseInsensitiveMap.class));
|
||||
assertNotNull("we should have gotten the result with upper case", out.get("A"));
|
||||
|
@ -1111,6 +1110,25 @@ public class JdbcTemplateTests {
|
|||
verify(this.connection).close();
|
||||
}
|
||||
|
||||
@Test // SPR-16578
|
||||
public void testEquallyNamedColumn() throws SQLException {
|
||||
given(this.connection.createStatement()).willReturn(this.statement);
|
||||
|
||||
ResultSetMetaData metaData = mock(ResultSetMetaData.class);
|
||||
given(metaData.getColumnCount()).willReturn(2);
|
||||
given(metaData.getColumnLabel(1)).willReturn("x");
|
||||
given(metaData.getColumnLabel(2)).willReturn("X");
|
||||
given(this.resultSet.getMetaData()).willReturn(metaData);
|
||||
|
||||
given(this.resultSet.next()).willReturn(true, false);
|
||||
given(this.resultSet.getObject(1)).willReturn("first value");
|
||||
given(this.resultSet.getObject(2)).willReturn("second value");
|
||||
|
||||
Map<String, Object> map = this.template.queryForMap("my query");
|
||||
assertEquals(1, map.size());
|
||||
assertEquals("first value", map.get("x"));
|
||||
}
|
||||
|
||||
|
||||
private void mockDatabaseMetaData(boolean supportsBatchUpdates) throws SQLException {
|
||||
DatabaseMetaData databaseMetaData = mock(DatabaseMetaData.class);
|
||||
|
|
Loading…
Reference in New Issue