我是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(&#34; TIPOREGALO_ID&#34;)));当前者对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失败并出现nullpointerexception
任何线索?
由于
答案 0 :(得分:1)
Add-Type -Path "Serilog.dll"
#Add-Type -Path "Serilog.Sinks.Seq.dll"
#Add-Type -Path "Serilog.Sinks.EventLog.dll"
Add-Type -Path "serilog.sinks.elasticsearch.dll"
Add-Type -Path "Serilog.FullNetFx.dll"
Add-Type -Path "Elasticsearch.Net.dll"
#Add-Type -Path "Serilog.Extras.AppSettings.dll"
#Add-Type -Path "Serilog.Extras.Timing.dll"
$config = New-Object -TypeName "Serilog.LoggerConfiguration"
[Serilog.Configuration.LoggerSinkConfiguration]$ConfigSink = $config.WriteTo
<#
[Serilog.Log]::Logger = [Serilog.LoggerConfigurationFullNetFxExtensions]::RollingFile
($ConfigSink,
"C:\Logs\Log-{Date}.txt",
([Serilog.Events.LogEventLevel]::Verbose), "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}", $null, 10000000, 15).CreateLogger()
#>
$config.CreateLogger()
[Serilog.Log]::Logger = [Serilog.LoggerConfigurationElasticsearchExtensions]::Elasticsearch($ConfigSink, "http://192.168.1.125:9200", "custom-index-{0:yyyy.MM}", "asdd"),
([Serilog.Events.LogEventLevel]::Verbose), "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}", $null, 10000000, 15).CreateLogger()
[Serilog.Log]::Information("Logging starte");
这会创建一个TipoRegaloDaoImpl,并且永远不会初始化它的TipoRegaloDao tipoRegaloDao = new TipoRegaloDaoImpl();
。 Spring只能自动装配自己创建的bean。不是您使用namedParameterJdbcTemplate
创建的。在RegaloDaoImpl中注入TipoRegaloDao(并使映射器成为内部类而不是嵌套的静态类,以允许它访问该字段)。
如果您使用构造函数注入而不是字段注入,那么您永远不会遇到此问题,因为很明显TipoRegaloDaoImpl需要一个namedParameterJdbcTemplate:它将是其构造函数参数之一。但总的来说,每次使用new
创建Spring bean时,都会出错。