Avoid RS.getObject(index, Object.class) as it breaks MySQL on Java 7

Previously, when running on Java 7+, the JDBC query driven by
DataSourceHealthIndicator resulted in a call to
ResultSet.getObject(index, Object.class). When using MySQL's JDBC
driver this failed with an SQLException with the message "Conversion
not supported for type java.lang.Object". The problem does not occur
on Java 6 as the overload of getObject that takes a type does not
exist; ResultSet.getObject(index) is called instead and MySQL happily
returns whatever type it deems to be appropriate for the column.

This commit updates DataSourceHealthIndicator so that
ResultSet.getObject(index) will always be used, irrespective of the
version of Java that Boot is running on.

Closes #1306
This commit is contained in:
Andy Wilkinson 2014-07-29 15:03:09 +01:00
parent 86d47f62db
commit 333bc3e842

View File

@ -17,6 +17,8 @@
package org.springframework.boot.actuate.health;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
@ -24,8 +26,12 @@ import java.util.Map;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.IncorrectResultSetColumnCountException;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.StringUtils;
/**
@ -34,6 +40,7 @@ import org.springframework.util.StringUtils;
*
* @author Dave Syer
* @author Christian Dupuis
* @author Andy Wilkinson
* @since 1.1.0
*/
public class DataSourceHealthIndicator extends AbstractHealthIndicator {
@ -86,8 +93,23 @@ public class DataSourceHealthIndicator extends AbstractHealthIndicator {
String query = detectQuery(product);
if (StringUtils.hasText(query)) {
try {
builder.withDetail("hello",
this.jdbcTemplate.queryForObject(query, Object.class));
builder.withDetail("hello", DataAccessUtils
.requiredSingleResult(this.jdbcTemplate.query(query,
new RowMapper<Object>() {
@Override
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
ResultSetMetaData rsmd = rs.getMetaData();
int nrOfColumns = rsmd.getColumnCount();
if (nrOfColumns != 1) {
throw new IncorrectResultSetColumnCountException(
1, nrOfColumns);
}
return JdbcUtils.getResultSetValue(rs, 1);
}
})));
}
catch (Exception ex) {
builder.down(ex);