select 操作的 JDBCTemplate 代码有什么问题?

What is wrong with my JDBCTemplate code for select operation?

它是一个简单的 table,有两列,我尝试使用 Spring 4.X 的 JdbcTemplate 进行 Dao 活动,看来我在这里做错了。请在下面找到我的代码:

@Named("CategoryDao")
public class CategoryDaoImpl implements CategoryDao {

    @Inject 
    private @Named("BlogDataSource")
            DataSource          dataSource;
    private JdbcTemplate        jdbcTemplate;
    private SimpleJdbcInsert    simpleJdbcInsert;

    /*
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }*/


    public JdbcTemplate getJdbcTemplate() {
        if (jdbcTemplate == null) {
            this.jdbcTemplate = new JdbcTemplate(dataSource);
        }
        return jdbcTemplate;
    }

    public SimpleJdbcInsert getSimpleJdbcInsert(){
        if (simpleJdbcInsert == null) {
            this.simpleJdbcInsert = new SimpleJdbcInsert(dataSource)
                    .withTableName("category")
                    .withSchemaName("sreedb")
                    .usingGeneratedKeyColumns("category_id");
        }
        return simpleJdbcInsert;
    }

    public RowMapper<Category> getRowMapper() {
        return new RowMapper<Category>() {
            public Category mapRow(ResultSet rs, int rowNum) throws SQLException {
                Category category = new Category();
                category.setId(rs.getInt("category_id"));
                category.setName(rs.getString("category_name"));
                return category;
            }
        };
    }

    public List<Category> createCategoryList(List<Map<String,Object>> rows){
        List<Category> categoryList = new ArrayList<Category>();
        for (Map<String, Object> row : rows) {
            Category category = new Category();
            category.setId(ObjectUtils.getInteger(row.get("category_id")));
            category.setName(ObjectUtils.getString(row.get("category_name")));
            categoryList.add(category);
        }       
        return categoryList;
    }

    public Map<String,Object> createCategoryParameterMap(Category category){
        Map<String,Object> parameters  = new HashMap<String,Object>();      
        parameters.put("category_name", category.getName());        
        return parameters;
    }


    public Integer save(Category category) {
        return getSimpleJdbcInsert()
                .executeAndReturnKey(createCategoryParameterMap(category))
                .intValue();

    }

    public void update(Category category) {
        String sql = "UPDATE category SET category_name = ?  WHERE category_id = ?" ;
        getJdbcTemplate().update(sql,category.getName(),category.getId() );     
    }

    public Category getCategoryById(Integer id) {
        String sql = "SELECT category_id, category_name FROM category"
                + " WHERE category_id = ?";
        return getJdbcTemplate().queryForObject(sql, getRowMapper(), id);       
    }

    public List<Category> getCategoryList() {
        String sql = "SELECT category_id, category_name FROM category" ;                
        return createCategoryList(getJdbcTemplate().queryForList(sql, getRowMapper()));
    }
}

当我调用 getCategoryList() 方法时,我收到以下执行错误。

org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [SELECT category_id, category_name FROM category]; Invalid argument value: java.io.NotSerializableException; nested exception is java.sql.SQLException: Invalid argument value: java.io.NotSerializableException
    org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:108)
    org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
    org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
    org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:645)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:772)
    org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:849)
    com.abcd.sree.dao.CategoryDaoImpl.getCategoryList(CategoryDaoImpl.java:103)
    com.abcd.sree.service.CategoryService.getCategoryList(CategoryService.java:28)
    com.abcd.sree.view.action.author.createCategoryActionBean.viewCategory(createCategoryActionBean.java:28)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:497)
    net.sourceforge.stripes.controller.DispatcherHelper.intercept(DispatcherHelper.java:456)
    net.sourceforge.stripes.controller.ExecutionContext.proceed(ExecutionContext.java:158)
    net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor.intercept(BeforeAfterMethodInterceptor.java:113)
    net.sourceforge.stripes.controller.ExecutionContext.proceed(ExecutionContext.java:155)
    net.sourceforge.stripes.controller.ExecutionContext.wrap(ExecutionContext.java:74)
    net.sourceforge.stripes.controller.DispatcherHelper.invokeEventHandler(DispatcherHelper.java:454)
    net.sourceforge.stripes.controller.DispatcherServlet.invokeEventHandler(DispatcherServlet.java:278)
    net.sourceforge.stripes.controller.DispatcherServlet.service(DispatcherServlet.java:160)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilter.java:260)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:742)
    org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:712)
    org.apache.jsp.index_jsp._jspService(index_jsp.java:131)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilter.java:260)
root cause

java.sql.SQLException: Invalid argument value: java.io.NotSerializableException
    com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
    com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
    com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
    com.mysql.jdbc.PreparedStatement.setSerializableObject(PreparedStatement.java:3920)
    com.mysql.jdbc.PreparedStatement.setObject(PreparedStatement.java:3564)
    com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setObject(NewProxyPreparedStatement.java:365)
    org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:427)
    org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:235)
    org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:166)
    org.springframework.jdbc.core.ArgumentPreparedStatementSetter.doSetValue(ArgumentPreparedStatementSetter.java:66)
    org.springframework.jdbc.core.ArgumentPreparedStatementSetter.setValues(ArgumentPreparedStatementSetter.java:47)
    org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:686)
    org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:772)
    org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:849)
    com.abcd.sree.dao.CategoryDaoImpl.getCategoryList(CategoryDaoImpl.java:103)
    com.abcd.sree.service.CategoryService.getCategoryList(CategoryService.java:28)
    com.abcd.sree.view.action.author.createCategoryActionBean.viewCategory(createCategoryActionBean.java:28)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:497)
    net.sourceforge.stripes.controller.DispatcherHelper.intercept(DispatcherHelper.java:456)
    net.sourceforge.stripes.controller.ExecutionContext.proceed(ExecutionContext.java:158)
    net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor.intercept(BeforeAfterMethodInterceptor.java:113)
    net.sourceforge.stripes.controller.ExecutionContext.proceed(ExecutionContext.java:155)
    net.sourceforge.stripes.controller.ExecutionContext.wrap(ExecutionContext.java:74)
    net.sourceforge.stripes.controller.DispatcherHelper.invokeEventHandler(DispatcherHelper.java:454)
    net.sourceforge.stripes.controller.DispatcherServlet.invokeEventHandler(DispatcherServlet.java:278)
    net.sourceforge.stripes.controller.DispatcherServlet.service(DispatcherServlet.java:160)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilter.java:260)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:742)
    org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:712)
    org.apache.jsp.index_jsp._jspService(index_jsp.java:131)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilter.java:260)
root cause

java.io.NotSerializableException: com.abcd.sree.dao.CategoryDaoImpl
    java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    com.mysql.jdbc.PreparedStatement.setSerializableObject(PreparedStatement.java:3909)
    com.mysql.jdbc.PreparedStatement.setObject(PreparedStatement.java:3564)
    com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setObject(NewProxyPreparedStatement.java:365)
    org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:427)
    org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:235)
    org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:166)
    org.springframework.jdbc.core.ArgumentPreparedStatementSetter.doSetValue(ArgumentPreparedStatementSetter.java:66)
    org.springframework.jdbc.core.ArgumentPreparedStatementSetter.setValues(ArgumentPreparedStatementSetter.java:47)
    org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:686)
    org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722)
    org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:772)
    org.springframework.jdbc.core.JdbcTemplate.queryForList(JdbcTemplate.java:849)
    com.abcd.sree.dao.CategoryDaoImpl.getCategoryList(CategoryDaoImpl.java:103)
    com.abcd.sree.service.CategoryService.getCategoryList(CategoryService.java:28)
    com.abcd.sree.view.action.author.createCategoryActionBean.viewCategory(createCategoryActionBean.java:28)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:497)
    net.sourceforge.stripes.controller.DispatcherHelper.intercept(DispatcherHelper.java:456)
    net.sourceforge.stripes.controller.ExecutionContext.proceed(ExecutionContext.java:158)
    net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor.intercept(BeforeAfterMethodInterceptor.java:113)
    net.sourceforge.stripes.controller.ExecutionContext.proceed(ExecutionContext.java:155)
    net.sourceforge.stripes.controller.ExecutionContext.wrap(ExecutionContext.java:74)
    net.sourceforge.stripes.controller.DispatcherHelper.invokeEventHandler(DispatcherHelper.java:454)
    net.sourceforge.stripes.controller.DispatcherServlet.invokeEventHandler(DispatcherServlet.java:278)
    net.sourceforge.stripes.controller.DispatcherServlet.service(DispatcherServlet.java:160)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilter.java:260)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:742)
    org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:712)
    org.apache.jsp.index_jsp._jspService(index_jsp.java:131)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilter.java:260)

在我看来它看起来不错,但我确定我做错了什么!!!有人可以阅读并弄清楚我哪里出了问题吗?

您正在尝试使用 RowMapper as second argument (converted to Object[]), which in turn was given as a parameter to the JDBC's PreparedStatement.setObject this is not what you intended, and cannot work in general because your implementation of RowMapper is not Serializable 调用 queryForList(String sql, Object... args) 方法。

None queryForList 方法接受 RowMapper as second argument and to get the result you're after use query(String, RowMapper<T>) 方法。