Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring JDBC BeanPropertyRowMapper yes no ('Y','N') to boolean bean properties

I have a class with some string, int and boolean fields. I have the getters and setters declared for them.

public class SomeClass {

    private int id;
    private String description;
    private boolean active;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public boolean isActive() {
        return active;
    }
    public void setActive(boolean active) {
        this.active = active;
    }


}

I am BeanPropertyRowMapper to get all the objects from and Oracle DB.

@Override
public List<Destination> getAll() {
     List<SomeClass> objs = jdbcTemplate.query(
                myQuery, new BeanPropertyRowMapper<SomeClass>(SomeClass.class));
     return objs;
}   

If the debug is turned on I see:

[3/14/13 10:02:09:202 EDT] 00000018 SystemOut     O DEBUG BeanPropertyRowMapper - Mapping column 'ID' to property 'id' of type int
[3/14/13 10:02:09:202 EDT] 00000018 SystemOut     O DEBUG BeanPropertyRowMapper - Mapping column 'DESCRIPTION' to property 'description' of type class java.lang.String

And then it fails trying to map active. Active is defined as 1 byte CHAR in the DB with values as 'Y' or 'N'. What is the best way to use BeanPropertyRowMapper and successfully convert values such as 'Y', and 'N' to boolean?

like image 727
MickJ Avatar asked Mar 14 '13 14:03

MickJ


People also ask

What is the use of BeanPropertyRowMapper?

Class BeanPropertyRowMapper<T> RowMapper implementation that converts a row into a new instance of the specified mapped target class. The mapped target class must be a top-level class and it must have a default or no-arg constructor.

Which of the following functionality are provided by JdbcTemplate in spring framework?

The JdbcTemplate class executes SQL queries, update statements and stored procedure calls, performs iteration over ResultSet s and extraction of returned parameter values.

Which of the following approaches does Spring framework provide for JDBC database access?

Spring framework provides the following approaches for JDBC database access: JdbcTemplate. NamedParameterJdbcTemplate. SimpleJdbcTemplate.

Which of the XML bean is used to hold database credentials in JDBC template?

In the application context XML file, which we call my-beans. xml , we define two beans: data source bean and jdbcTemplate bean. The data source bean contains the data source properties; the jdbcTemplate refers to the dataSource bean via the ref attribute. The my-beans.


1 Answers

So I figured out how to do this. I extended BeanPropertyRowMapper and handler boolean types through some custom code before handing off the control to beanpropertyrowmapper for rest of the data types.

Note: It works for me because I use oracle and all of the 'boolean' type columns are strings with 'y','yes','n' & 'no' type values.

Those who use numerical 1,0 or other formats could potentially improve it further by making it generic through an object yes map and getting objects from resultset and looking them up in this map. Hope this helps someone else in a situation like mine.

import java.beans.PropertyDescriptor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;

/**
 * Extends BeanPropertyRowMapper to allow for boolean fields
 * mapped to 'Y,'N' type column to get set correctly. Using stock BeanPropertyRowMapper
 * would throw a SQLException.
 * 
 */
public class ExtendedBeanPropertyRowMapper<T> extends BeanPropertyRowMapper<T> {

    //Contains valid true values
    public static final Set<String> TRUE_SET = new HashSet<String>(Arrays.asList("y", "yes", "true"));

    public ExtendedBeanPropertyRowMapper(Class<T> class1) {
        super(class1);
    }

    @Override
    /**
     * Override <code>getColumnValue</code> to add ability to map 'Y','N' type columns to
     * boolean properties.
     * 
     * @param rs is the ResultSet holding the data
     * @param index is the column index
     * @param pd the bean property that each result object is expected to match
     * (or <code>null</code> if none specified)
     * @return the Object value
     * @throws SQLException in case of extraction failure
     * @see org.springframework.jdbc.core.BeanPropertyRowMapper#getColumnValue(java.sql.ResultSet, int, PropertyDescriptor) 
     */
    protected Object getColumnValue(ResultSet rs, int index,
            PropertyDescriptor pd) throws SQLException {
        Class<?> requiredType = pd.getPropertyType();
        if (boolean.class.equals(requiredType) || Boolean.class.equals(requiredType)) {
            String stringValue = rs.getString(index);
            if(!StringUtils.isEmpty(stringValue) && TRUE_SET.contains(stringValue.toLowerCase())){
                return true;
            }
            else return false;
        }       
        return super.getColumnValue(rs, index, pd);
    }
}
like image 135
MickJ Avatar answered Sep 24 '22 06:09

MickJ