Spring - How to use BeanPropertyRowMapper without matching column names

I saw Some posts about using aliases in queries

This is actually an approach suggested in JavaDocs:

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".

From: BeanPropertyRowMapper.

impossible to do a SELECT *

Please do not use SELECT *. This makes you vulnerable to any database schema change, including completely backward compatible ones like adding or rearranging columns.

Isn't there any annotation that can be used with BeanPropertyRowMapper as @Column from JPA?

Yes, it is called jpa, hibernate and maybe ibatis. Seriously, either use aliases or implement your own RowMapper, Spring is not a full-featured orm.


You can override the BeanPropertyRowMapper.underscoreName, and get the name of the Column annotation to mapping the field with @Column(name = "EXAMPLE_KEY") in the PropertyDescriptor(getter/setter binding).

@Slf4j
public class ColumnRowMapper<T> extends BeanPropertyRowMapper<T> {

  private ColumnRowMapper(final Class<T> mappedClass)
  {
    super(mappedClass);
  }

  @Override
  protected String underscoreName(final String name)
  {
    final Column annotation;
    final String columnName;
    Field declaredField = null;

    try
    {
      declaredField = getMappedClass().getDeclaredField(name);
    }
    catch (NoSuchFieldException | SecurityException e)
    {
      log.warn("Ups, field «{}» not found in «{}».", name, getMappedClass());
    }

    if (declaredField == null || (annotation = declaredField.getAnnotation(Column.class)) == null
        || StringUtils.isEmpty(columnName = annotation.name()))
    {
      return super.underscoreName(name);
    }

    return StringUtils.lowerCase(columnName);
  }

  /**
   * New instance.
   *
   * @param <T> the generic type
   * @param mappedClass the mapped class
   * @return the bean property row mapper
   */
  public static <T> BeanPropertyRowMapper<T> newInstance(final Class<T> mappedClass)
  {
    return new ColumnRowMapper<>(mappedClass);
  }
}

Tags:

Java

Spring