2016-03-05 2 views
-1

Im kindda new to Spring, и я использую Spring mvc для создания простой веб-страницы, которая подключается к mysql db, но я получаю нулевые указатели, где я пытаюсь использовать запрос NamedParameterJdbcTemplate где другой NamedParameterJdbcTemplate в настоящее время осуществляетИспользование NamedParameterJdbcTemplate изнутри собственного Mapper

определение дб его вменяемым через эту конфигурацию боба (весна-веб-servlet.xml)

<bean id="dataSource" destroy-method="close" 
    class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
    <property name="url" 
     value="jdbc:mysql://#{systemEnvironment[OPENSHIFT_MYSQL_DB_HOST]}:#{systemEnvironment[OPENSHIFT_MYSQL_DB_PORT]}/#{systemEnvironment[OPENSHIFT_APP_NAME]}" /> 
    <property name="username" 
     value="#{systemEnvironment[OPENSHIFT_MYSQL_DB_USERNAME]}" /> 
    <property name="password" 
     value="#{systemEnvironment[OPENSHIFT_MYSQL_DB_PASSWORD]}" /> 
    <property name="initialSize" value="3" /> 
</bean> 

И этот конфигурационный класс (SpringDBConfig.java)

@Configuration 
public class SpringDBConfig { 
    @Autowired 
    DataSource dataSource; 

    @Bean 
    public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { 
     return new NamedParameterJdbcTemplate(dataSource); 
    } 
} 

Прежде всего моей БД такого рода

CREATE TABLE `TIPOSREGALO` (
    `TIPOREGALO_ID` varchar(50) NOT NULL, 
    `DESCRIPCION` varchar(5000) NOT NULL, 
    `URLFOTO` varchar(255) NOT NULL, 
    PRIMARY KEY (`TIPOREGALO_ID`) USING BTREE 
) ENGINE=INNODB DEFAULT CHARSET=utf8; 

CREATE TABLE `REGALOS` (
    `REGALO_ID` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `TIPOREGALO_ID` varchar(50) NOT NULL, 
    `TITULO` varchar(50) NOT NULL, 
    `DESCRIPCION` varchar(5000) NOT NULL, 
    `URLFOTO` varchar(255) NOT NULL, 
    `PRECIO` integer unsigned NOT NULL, 
    PRIMARY KEY (`REGALO_ID`) USING BTREE, 
    FOREIGN KEY (`TIPOREGALO_ID`) REFERENCES `TIPOSREGALO`(`TIPOREGALO_ID`) 
) ENGINE=INNODB DEFAULT CHARSET=utf8; 

Мой DAO его называют из контроллера, как так

@RequestMapping(value = "/gift/{id}", method = RequestMethod.GET) 
public String giftdetail(@PathVariable("id") int regalo_id, Model model) { 
    model.addAttribute("regalo", regaloService.findById(regalo_id)); 
    return "weddinglist/gift"; 
} 

Этот метод RegaloService является

@Override 
public Regalo findById(int id) { 
    return regaloDao.findById(id); 
} 

И regaloDao является

@Repository 
    public class RegaloDaoImpl implements RegaloDao { 

     private final Logger logger = LoggerFactory.getLogger(RegaloDaoImpl.class); 

     NamedParameterJdbcTemplate namedParameterJdbcTemplate; 

     @Autowired 
     public void setNamedParameterJdbcTemplate(
       NamedParameterJdbcTemplate namedParameterJdbcTemplate) 
       throws DataAccessException { 
      this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; 
     } 

     @Override 
     public Regalo findById(Integer regalo_id) { 
      logger.debug("findById() id: \"{}\"", regalo_id); 

      Map<String, Object> params = new HashMap<String, Object>(); 
      params.put("regalo_id", regalo_id); 

      String sql = "SELECT * FROM REGALOS WHERE REGALO_ID=:regalo_id"; 

      Regalo result = null; 
      try { 
       result = namedParameterJdbcTemplate.queryForObject(sql, params, 
         new RegaloMapper()); 
      } catch (EmptyResultDataAccessException e) { 
       // do nothing, return null 
      } 
      return result; 
     } 
    ... 

     private static final class RegaloMapper implements RowMapper<Regalo> { 

      private final Logger logger = LoggerFactory 
       .getLogger(RegaloMapper.class); 

      public Regalo mapRow(ResultSet rs, int rowNum) throws SQLException { 


       Regalo regalo = new Regalo(); 
       regalo.setRegalo_id(rs.getInt("REGALO_ID")); 

       TipoRegaloDao tipoRegaloDao = new TipoRegaloDaoImpl(); 
       regalo.setTiporegalo(tipoRegaloDao.findById(rs 
         .getString("TIPOREGALO_ID"))); 

       regalo.setTitulo(rs.getString("TITULO")); 
       regalo.setDescripcion(rs.getString("DESCRIPCION")); 
       regalo.setUrlfoto(rs.getString("URLFOTO")); 
       regalo.setPrecio(rs.getInt("PRECIO")); 
       return regalo; 
      } 
     } 
    } 

Как вы можете видеть, вызов regalo.setTiporegalo (tipoRegaloDao.findById (rs.getString («TIPOREGALO_ID»)); производится внутри Mapper, когда прежний призыв к queryForObject разве закончена, то выполнение переходит к TipoRegaloDaoImpl.findById() и пытается вызвать обнулен объект namedParameterJdbcTemplate

@Repository 
public class TipoRegaloDaoImpl implements TipoRegaloDao { 

    private final Logger logger = LoggerFactory 
      .getLogger(TipoRegaloDaoImpl.class); 

    NamedParameterJdbcTemplate namedParameterJdbcTemplate; 

    @Autowired 
    public void setNamedParameterJdbcTemplate(
      NamedParameterJdbcTemplate namedParameterJdbcTemplate) 
      throws DataAccessException { 
     logger.debug("setNamedParameterJdbcTemplate() namedParameterJdbcTemplate: \"{}\"", namedParameterJdbcTemplate); 
     this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; 
    } 

    @Override 
    public TipoRegalo findById(String tiporegalo_id) { 
     logger.debug("findById() id: \"{}\"", tiporegalo_id); 

     Map<String, Object> params = new HashMap<String, Object>(); 
     params.put("tiporegalo_id", tiporegalo_id); 

     String sql = "SELECT * FROM TIPOSREGALO WHERE TIPOREGALO_ID=:tiporegalo_id"; 

     TipoRegalo result = null; 
     try { 
      result = namedParameterJdbcTemplate.queryForObject(sql, params, 
         new TipoRegaloMapper()); 

      logger.debug("findById() result: \"{}\"", result); 


     } catch (EmptyResultDataAccessException e) { 
      logger.error("findById() Resultado vacio, excepcion " + e); 
      // do nothing, return null 
     } catch (Exception e) { 
      logger.error("findById() No se que ha pasado aqui, excepcion " + e); 
      // do nothing, return null 
     } 
     return result; 
    } 
.... 

И queryForObject терпит неудачу с NullPointerException

Любой ключи?

Благодаря

ответ

1
TipoRegaloDao tipoRegaloDao = new TipoRegaloDaoImpl(); 

Это создает TipoRegaloDaoImpl, и никогда не инициализирует namedParameterJdbcTemplate. Весна может только автообновить бобы, которые она сама создает. Не те, которые вы создаете сами, используя new. Внесите TipoRegaloDao внутри RegaloDaoImpl (и сделайте mapper внутренним классом вместо вложенного статического класса, чтобы он мог получить доступ к полю).

У вас никогда не будет этой проблемы, если вы использовали инъекцию конструктора, а не инъекцию поля, потому что тогда было бы очевидно, что TipoRegaloDaoImpl нуждается в namedParameterJdbcTemplate: это был бы один из аргументов конструктора. Но в общем, каждый раз, когда вы используете new для создания фасоли весны, что-то не так.

Смежные вопросы