BeanPropertyRowMapper not converting mysql tinyint 1 to boolean true

Viewed 35
public class Foo {
    private long id;
    private String name;
    private boolean isBar;

    public long getId() {
        return id;   
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return name;   
    }
    public void setName(String name) {
        this.name = name;
    }
    public boolean isBar() {
        return isBar;
    }
    public void setBar(boolean isBar) {
        this.isBar = isBar;
    }
}

@Component
public class FooDAO {
    private JdbcTemplate jdbcTemplate;

    private FooDAO(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
   
    public List<Foo> findAll() {
        return jdbcTemplate.query( "SELECT * FROM foo", new BeanPropertyRowMapper<>(Foo.class);
    }
}

When I setup a custom FooRowMapper and manually call setBar(rs.getBoolean("is_bar")) Foo.isBar is properly getting set to true when db value is 1, but not when using the BeanPropertyRowMapper instead of a custom row mapper.

According to this, BeanPropertyRowMapper should properly convert 1 to true, so why isn't it in my case?

p.s. I already figured out why but thought I'd post it in case it's helpful to anybody. I'm sure it won't take long for someone else to figure it out and post the answer.

1 Answers

I knew this:

Column values are mapped based on matching the column name as obtained from result set meta-data to public setters for the corresponding properties. The names are matched either directly or by transforming a name separating the parts with underscores to the same name using "camel" case.

But got thrown off because my Foo.isBar property had the correct camel case equivalent of my db field name (is_bar), however, my public setter name was incorrect as setBar; the setter should be setIsBar.

After googling I was also thrown off by others wanting to use BeanPropertyRowMapper to convert database values of Y/N to boolean values.

And I also assumed BeanPropertyRowMapper was actually setting the value to false even though it wasn't and the false value simply remained as the default boolean primitive value.

Another solution if for whatever reason setBar instead setIsBar was actually desired would be to use an field alias in the sql select statement like it says in the docs:

To facilitate mapping between columns and fields that don't have matching names, try using column aliases in the SQL statement like "select fname as first_name from customer".

Related