【发布时间】:2016-03-05 18:54:59
【问题描述】:
我对 Spring 有点陌生,我正在使用 spring mvc 编写一个连接到 mysql db 的简单网页,但我得到空指针,我尝试在另一个 NamedParameterJdbcTemplate 当前正在执行的地方使用 NamedParameterJdbcTemplate 查询
通过此 bean 配置 (spring-web-servlet.xml) 进行的 db 定义
<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")));当之前对 queryForObject 的调用没有完成时,在 Mapper 内部进行,然后执行到 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 因空指针异常而失败
有什么线索吗?
谢谢
【问题讨论】:
标签: java mysql spring spring-mvc