Tobia Tobia - 6 months ago 19
Java Question

Reflection mapping with primitive types

I needed a nestable bean rowmapper for JDBC, I used:

public class NestedRowMapper<T> implements RowMapper<T> {

private static Logger log = LoggerFactory.getLogger(NestedRowMapper.class);

private Class<T> mappedClass;

public NestedRowMapper(Class<T> mappedClass) {
this.mappedClass = mappedClass;
}

@Override
public T mapRow(ResultSet rs, int rowNum) throws SQLException {

T mappedObject = BeanUtils.instantiate(this.mappedClass);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(mappedObject);

bw.setAutoGrowNestedPaths(true);

ResultSetMetaData meta_data = rs.getMetaData();
int columnCount = meta_data.getColumnCount();

for (int index = 1; index <= columnCount; index++) {

String column=null;
Object value=null;
try {

column = JdbcUtils.lookupColumnName(meta_data, index);
value = JdbcUtils.getResultSetValue(rs, index, Class.forName(meta_data.getColumnClassName(index)));

bw.setPropertyValue(column, value);

} catch (TypeMismatchException | NotWritablePropertyException | ClassNotFoundException e) {
log.error("",column,value,bw.getClass().getSimpleName(),e);
}
}

return mappedObject;
}
}


This well works, except when it found a primitive type, in that case BeanWrapper.setPropertyValue fails.

For example, if in my mapped bean there is a boolean (primitive) instead of Boolean (class) property, it fails. How can I correct it to let it map also primitive type property?

Answer

I think you can check the source code org.springframework.jdbc.core.BeanPropertyRowMapper, you need get class type from the java class define, not from the ResultSet metadata.

for example, replace your Class.forName(meta_data.getColumnClassName(index) with following method getClass(column)

private Class<?> getClass(String column) {
    PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(this.mappedClass);
    for (PropertyDescriptor pd : pds) {
        if (pd.getName().equals(column)) {
            return pd.getPropertyType();
        }
    }
    return null;
}

it just an example, you need do cache/try catch like BeanPropertyRowMapper

Comments