Jdbctemplate query for string: EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

前端 未结 17 1156
执笔经年
执笔经年 2020-11-29 16:22

I am using Jdbctemplate to retrieve a single String value from the db. Here is my method.

    public String test() {
        String cert=null;
        Strin         


        
相关标签:
17条回答
  • 2020-11-29 16:56

    Using Java 8 or above you can use an Optional and Java Streams.

    So you can simply use the JdbcTemplate.queryForList() method, create a Stream and use Stream.findFirst() which will return the first value of the Stream or an empty Optional:

    public Optional<String> test() {
        String sql = "select ID_NMB_SRZ from codb_owner.TR_LTM_SLS_RTN where id_str_rt = '999' and ID_NMB_SRZ = '60230009999999'";
        return jdbc.queryForList(sql, String.class)
                .stream().findFirst();
    }
    

    To improve the performance of the query you can append LIMIT 1 to your query, so not more than 1 item is transferred from the database.

    0 讨论(0)
  • 2020-11-29 16:56

    You can do this way:

    String cert = DataAccessUtils.singleResult(
        jdbcTemplate.queryForList(
            "select ID_NMB_SRZ from codb_owner.TR_LTM_SLS_RTN where ID_STR_RT = :id_str_rt and ID_NMB_SRZ = :id_nmb_srz",
            new MapSqlParameterSource()
                .addValue("id_str_rt", "999")
                .addValue("id_nmb_srz", "60230009999999"),
            String.class
        )
    )
    

    DataAccessUtils.singleResult + queryForList:

    • returns null for empty result
    • returns single result if exactly 1 row found
    • throws exception if more then 1 rows found. Should not happen for primary key / unique index search

    DataAccessUtils.singleResult

    0 讨论(0)
  • 2020-11-29 16:57

    You could use a group function so that your query always returns a result. ie

    MIN(ID_NMB_SRZ)
    
    0 讨论(0)
  • 2020-11-29 16:57

    In Postgres, you can make almost any single value query return a value or null by wrapping it:

    SELECT (SELECT <query>) AS value
    

    and hence avoid complexity in the caller.

    0 讨论(0)
  • 2020-11-29 16:57

    I dealt with this before & had posted in the spring forums.

    http://forum.spring.io/forum/spring-projects/data/123129-frustrated-with-emptyresultdataaccessexception

    The advice we received was to use a type of SQlQuery. Here's an example of what we did when trying to get a value out of a DB that might not be there.

    @Component
    public class FindID extends MappingSqlQuery<Long> {
    
            @Autowired
            public void setDataSource(DataSource dataSource) {
    
                    String sql = "Select id from address where id = ?";
    
                    super.setDataSource(dataSource);
    
                    super.declareParameter(new SqlParameter(Types.VARCHAR));
    
                    super.setSql(sql);
    
                    compile();
            }
    
            @Override
            protected Long mapRow(ResultSet rs, int rowNum) throws SQLException {
                    return rs.getLong(1);
            }
    

    In the DAO then we just call...

    Long id = findID.findObject(id);
    

    Not clear on performance, but it works and is neat.

    0 讨论(0)
  • 2020-11-29 16:59

    We can use query instead of queryForObject, major difference between query and queryForObject is that query return list of Object(based on Row mapper return type) and that list can be empty if no data is received from database while queryForObject always expect only single object be fetched from db neither null nor multiple rows and in case if result is empty then queryForObject throws EmptyResultDataAccessException, I had written one code using query that will overcome the problem of EmptyResultDataAccessException in case of null result.

    ----------
    
    
    public UserInfo getUserInfo(String username, String password) {
          String sql = "SELECT firstname, lastname,address,city FROM users WHERE id=? and pass=?";
          List<UserInfo> userInfoList = jdbcTemplate.query(sql, new Object[] { username, password },
                  new RowMapper<UserInfo>() {
                      public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
                          UserInfo user = new UserInfo();
                          user.setFirstName(rs.getString("firstname"));
                          user.setLastName(rs.getString("lastname"));
                          user.setAddress(rs.getString("address"));
                          user.setCity(rs.getString("city"));
    
                          return user;
                      }
                  });
    
          if (userInfoList.isEmpty()) {
              return null;
          } else {
              return userInfoList.get(0);
          }
      }
    
    0 讨论(0)
提交回复
热议问题