diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java index 5ae9462e97b..52d363db667 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java @@ -236,8 +236,8 @@ public class BeanPropertyRowMapper implements RowMapper { Set populatedProperties = (isCheckFullyPopulated() ? new HashSet() : null); for (int index = 1; index <= columnCount; index++) { - String column = JdbcUtils.lookupColumnName(rsmd, index).toLowerCase(); - PropertyDescriptor pd = this.mappedFields.get(column); + String column = JdbcUtils.lookupColumnName(rsmd, index); + PropertyDescriptor pd = this.mappedFields.get(column.replaceAll(" ", "").toLowerCase()); if (pd != null) { try { Object value = getColumnValue(rs, index, pd); diff --git a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java index f31d3dd025c..551efe2baae 100644 --- a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java +++ b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.java @@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.core.test.ConcretePerson; import org.springframework.jdbc.core.test.Person; +import org.springframework.jdbc.core.test.SpacePerson; import org.springframework.jdbc.datasource.SingleConnectionDataSource; import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; @@ -48,6 +49,9 @@ public abstract class AbstractRowMapperTests extends TestCase { protected Connection con; protected MockControl conControl2; protected Connection con2; + protected MockControl conControl3; + protected Connection con3; + protected MockControl rsmdControl; protected ResultSetMetaData rsmd; protected MockControl rsControl; @@ -55,6 +59,7 @@ public abstract class AbstractRowMapperTests extends TestCase { protected MockControl stmtControl; protected Statement stmt; protected JdbcTemplate jdbcTemplate; + protected MockControl rsmdControl2; protected ResultSetMetaData rsmd2; protected MockControl rsControl2; @@ -63,6 +68,14 @@ public abstract class AbstractRowMapperTests extends TestCase { protected Statement stmt2; protected JdbcTemplate jdbcTemplate2; + protected MockControl rsmdControl3; + protected ResultSetMetaData rsmd3; + protected MockControl rsControl3; + protected ResultSet rs3; + protected MockControl stmtControl3; + protected Statement stmt3; + protected JdbcTemplate jdbcTemplate3; + protected void setUp() throws SQLException { conControl = MockControl.createControl(Connection.class); con = (Connection) conControl.getMock(); @@ -119,6 +132,9 @@ public abstract class AbstractRowMapperTests extends TestCase { stmt.close(); stmtControl.setVoidCallable(1); + conControl.replay(); + stmtControl.replay(); + conControl2 = MockControl.createControl(Connection.class); con2 = (Connection) conControl2.getMock(); con2.isClosed(); @@ -174,11 +190,67 @@ public abstract class AbstractRowMapperTests extends TestCase { stmt2.close(); stmtControl2.setVoidCallable(2); - conControl.replay(); - stmtControl.replay(); conControl2.replay(); stmtControl2.replay(); + conControl3 = MockControl.createControl(Connection.class); + con3 = (Connection) conControl3.getMock(); + con3.isClosed(); + conControl3.setDefaultReturnValue(false); + + rsmdControl3 = MockControl.createControl(ResultSetMetaData.class); + rsmd3 = (ResultSetMetaData)rsmdControl3.getMock(); + rsmd3.getColumnCount(); + rsmdControl3.setReturnValue(4, 1); + rsmd3.getColumnLabel(1); + rsmdControl3.setReturnValue("Last Name", 1); + rsmd3.getColumnLabel(2); + rsmdControl3.setReturnValue("age", 1); + rsmd3.getColumnLabel(3); + rsmdControl3.setReturnValue("birth_date", 1); + rsmd3.getColumnLabel(4); + rsmdControl3.setReturnValue("balance", 1); + rsmdControl3.replay(); + + rsControl3 = MockControl.createControl(ResultSet.class); + rs3 = (ResultSet) rsControl3.getMock(); + rs3.getMetaData(); + rsControl3.setReturnValue(rsmd3, 1); + rs3.next(); + rsControl3.setReturnValue(true, 1); + rs3.getString(1); + rsControl3.setReturnValue("Gagarin", 1); + rs3.wasNull(); + rsControl3.setReturnValue(false, 1); + rs3.getLong(2); + rsControl3.setReturnValue(22, 1); + rs3.getTimestamp(3); + rsControl3.setReturnValue(new Timestamp(1221222L), 1); + rs3.getBigDecimal(4); + rsControl3.setReturnValue(new BigDecimal("1234.56"), 1); + rs3.next(); + rsControl3.setReturnValue(false, 1); + rs3.close(); + rsControl3.setVoidCallable(1); + rsControl3.replay(); + + stmtControl3 = MockControl.createControl(Statement.class); + stmt3 = (Statement) stmtControl3.getMock(); + + con3.createStatement(); + conControl3.setReturnValue(stmt3, 1); + stmt3.executeQuery("select last_name as \"Last Name\", age, birth_date, balance from people"); + stmtControl3.setReturnValue(rs3, 1); + if (debugEnabled) { + stmt3.getWarnings(); + stmtControl3.setReturnValue(null, 1); + } + stmt3.close(); + stmtControl3.setVoidCallable(1); + + conControl3.replay(); + stmtControl3.replay(); + jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(new SingleConnectionDataSource(con, false)); jdbcTemplate.setExceptionTranslator(new SQLStateSQLExceptionTranslator()); @@ -188,6 +260,11 @@ public abstract class AbstractRowMapperTests extends TestCase { jdbcTemplate2.setDataSource(new SingleConnectionDataSource(con2, false)); jdbcTemplate2.setExceptionTranslator(new SQLStateSQLExceptionTranslator()); jdbcTemplate2.afterPropertiesSet(); + + jdbcTemplate3 = new JdbcTemplate(); + jdbcTemplate3.setDataSource(new SingleConnectionDataSource(con3, false)); + jdbcTemplate3.setExceptionTranslator(new SQLStateSQLExceptionTranslator()); + jdbcTemplate3.afterPropertiesSet(); } protected void verifyPerson(Person bean) { @@ -217,6 +294,17 @@ public abstract class AbstractRowMapperTests extends TestCase { assertEquals(new BigDecimal("1234.56"), bean.getBalance()); } + protected void verifySpacePerson(SpacePerson bean) { + conControl3.verify(); + rsControl3.verify(); + rsmdControl3.verify(); + stmtControl3.verify(); + assertEquals("Gagarin", bean.getLastName()); + assertEquals(22L, bean.getAge()); + assertEquals(new java.util.Date(1221222L), bean.getBirthDate()); + assertEquals(new BigDecimal("1234.56"), bean.getBalance()); + } + private void verify() { conControl.verify(); rsControl.verify(); diff --git a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.java b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.java index 718ddf4518f..006666d1ce8 100644 --- a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.java +++ b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.java @@ -23,6 +23,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.test.ConcretePerson; import org.springframework.jdbc.core.test.ExtendedPerson; import org.springframework.jdbc.core.test.Person; +import org.springframework.jdbc.core.test.SpacePerson; import org.springframework.beans.TypeMismatchException; /** @@ -108,4 +109,12 @@ public class BeanPropertyRowMapperTests extends AbstractRowMapperTests { verifyPersonWithZeroAge(bean); } + public void testQueryWithSpaceInColumnName() throws SQLException { + List result = jdbcTemplate3.query("select last_name as \"Last Name\", age, birth_date, balance from people", + new BeanPropertyRowMapper(SpacePerson.class)); + assertEquals(1, result.size()); + SpacePerson bean = (SpacePerson) result.get(0); + verifySpacePerson(bean); + } + } diff --git a/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/test/SpacePerson.java b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/test/SpacePerson.java new file mode 100644 index 00000000000..b6ad9f9da3b --- /dev/null +++ b/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/test/SpacePerson.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002-2008 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.core.test; + +import java.math.BigDecimal; + +/** + * @author Thomas Risberg + */ +public class SpacePerson { + + private String lastName; + + private long age; + + private java.util.Date birthDate; + + private BigDecimal balance; + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public long getAge() { + return age; + } + + public void setAge(long age) { + this.age = age; + } + + public java.util.Date getBirthDate() { + return birthDate; + } + + public void setBirth_date(java.util.Date birthDate) { + this.birthDate = birthDate; + } + + public BigDecimal getBalance() { + return balance; + } + + public void setBalance(BigDecimal balanace) { + this.balance = balanace; + } + +} \ No newline at end of file