Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bad grammar SQL Exception while reading the values using rowmapper

This is my Model class

//Model

    public class CustomerData {

        private String locomotive_id;
        private String customer_name;
        private String road_number;
        private String locomotive_type_code;
        private String in_service_date;
        private String part_number;
        private String emission_tier_type;
        private String airbrake_type_code;
        private String lms_fleet;
        private String aar_road;
        private String locomotive_status_code;

        // Getters and Setters

Here is my RowMapper implementation

//RowMapper

    public class CustomerDataResponseMapper implements RowMapper {

    @Override
    public Object mapRow(ResultSet rs, int count) throws SQLException {
        CustomerData customerData = new CustomerData();

        customerData.setLocomotive_id(rs.getString("locomotive_id"));
        customerData.setCustomer_name(rs.getString("customer_name"));
        customerData.setRoad_number(rs.getString("road_number"));
        customerData.setLocomotive_type_code(rs.getString("locomotive_type_code"));
        customerData.setIn_service_date(rs.getString("in_service_date"));
        customerData.setPart_number(rs.getString("part_number"));
        customerData.setEmission_tier_type(rs.getString("emission_tier_type"));
        customerData.setAirbrake_type_code(rs.getString("airbrake_type_code"));
        customerData.setLms_fleet(rs.getString("lms_fleet"));
        customerData.setAar_road(rs.getString("aar_road"));
        customerData.setLocomotive_status_code(rs.getString("locomotive_status_code"));

        return customerData;
    }

}

And finally, I got my DaoImpl class here

//DaoImpl
    public String getCustomersData(String locoId, String custName, String roadNumber) {
        CustomerData resultSet = null;
        String str = "";
        if (locoId != null && locoId.length() > 0 && !(locoId.equals("0"))) {
            str = "select   locomotive_id,customer_name,road_number,model_type as locomotive_type_code,to_char(in_service_date,'yyyy-mm-dd') as in_service_date,loco_part_number as part_number,    emission_tier_type as emission_tier_type, "
                    + "air_brake_type as airbrake_type_code,lms_fleet,aar_road,locomotive_status_code   from get_rdf_explorer.get_rdf_locomotive_detail  where locomotive_id = ?";
            resultSet = (CustomerData) jdbcTemplate.queryForObject(str, new CustomerDataResponseMapper(), locoId);
        } else if ((custName != null && custName.length() > 0)
                && (roadNumber != null && roadNumber.length() > 0 && roadNumber != "0")) {
            str = "select   locomotive_id,customer_name,road_number,model_type as locomotive_type_code,to_char(in_service_date,'yyyy-mm-dd') as in_service_date,loco_part_number as part_number,    emission_tier_type as emission_tier_type, "
                    + "air_brake_type as airbrake_type_code,lms_fleet,aar_road,locomotive_status_code   from get_rdf_explorer.get_rdf_locomotive_detail  where customer_name = ? and road_number= ?";
            resultSet = (CustomerData) jdbcTemplate.queryForObject(str, new CustomerDataResponseMapper(), custName, roadNumber);
        } else {
            str = "select distinct customer_name from get_rdf_explorer.get_rdf_locomotive_detail order by customer_name asc";
            resultSet = (CustomerData) jdbcTemplate.queryForObject(str, new CustomerDataResponseMapper());
        }
        return resultSet.toString();
    }

How can I conditionally get the values from the resultSet based on whether a particular column is present in the resultSet or not. As I am not getting all the columns all the time through my queries.

I am getting SQL bad grammar exception when specific column is not present in resultSet. For example when the third query to get distinct customer names get executed, in the resultSet only customerName would be there, but not the other columns.

It would be really a great help. Thanks a lot in advance.

like image 439
Santosh Anantharamaiah Avatar asked Jul 16 '17 20:07

Santosh Anantharamaiah


2 Answers

Since you already have 3 separate queries why not have 3 separate RowMappers, one for each query. Your queries "know" what columns they return, so you can easily create those classes for RowMapper.

If you really want High-Fidelity solution you could create abstract base RowMapper for common parts and 3 subclasses for parts specifig to the query.

like image 128
ikettu Avatar answered Sep 28 '22 15:09

ikettu


You can use a generic method which investigates the ResultSet's columns

@SuppressWarnings("unchecked")
public <T> T getColIfPresent(ResultSet rs, String columnName) throws SQLException {
    ResultSetMetaData metaData = rs.getMetaData();
    for (int i = 1; i <= metaData.getColumnCount(); i++) {
        if (columnName.equals(metaData.getColumnName(i))) {
            return (T) rs.getObject(columnName);
        }
    }
    return null;// not present
}

Then, in row mapper.

customerData.setLocomotive_id(getColIfPresent(rs, "locomotive_id"));
...

This has O(n*m) complexity where n - the number of columns checked, m - the number of columns returned in ResultSet.

If you choose to ignore the SQLException, at least log it in DEBUG or TRACE level in case a different subtype of SQLException occurs, so that it's not lost.

like image 35
isah Avatar answered Sep 28 '22 14:09

isah