Spring - 无效的参数值:java.io.NotSerializableException

10

我试图向表中插入一条记录时出现以下错误: 我也尝试在SQL语句中使用“?”作为参数,但仍然收到相同的错误提示。

错误提示

54080 [http-8084-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - Finished creating instance of bean 'Sybase'
54080 [http-8084-2] INFO  org.springframework.jdbc.support.SQLErrorCodesFactory  - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
54080 [http-8084-2] DEBUG org.springframework.jdbc.support.SQLErrorCodesFactory  - Looking up default SQLErrorCodes for DataSource [org.apache.commons.dbcp.BasicDataSource@1e20a9a]
54083 [http-8084-2] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Fetching JDBC Connection from DataSource
54085 [http-8084-2] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Returning JDBC Connection to DataSource
54085 [http-8084-2] DEBUG org.springframework.jdbc.support.SQLErrorCodesFactory  - Database product name cached for DataSource [org.apache.commons.dbcp.BasicDataSource@1e20a9a]: name is 'MySQL'
54090 [http-8084-2] DEBUG org.springframework.jdbc.support.SQLErrorCodesFactory  - SQL error codes for 'MySQL' found
54090 [http-8084-2] DEBUG org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator  - Unable to translate SQLException with Error code '0', will now try the fallback translator
54091 [http-8084-2] DEBUG org.springframework.jdbc.support.SQLStateSQLExceptionTranslator  - Extracted SQL state class 'S1' from value 'S1009'
54092 [http-8084-2] INFO  com.crimetrack.jdbc.JdbcOfficersDAO  - PreparedStatementCallback; SQL [INSERT INTO crimetrack.tblofficers (userName,password, fName, lName, oName, divisionNo, poisitionId, emailAdd, startDate, endDate, genderId, phoneNo, dob) VALUES (:userName,:password, :fName, :lName, :oName, :divisionNo, :poisitionId, :emailAdd, :startDate, :endDate, :genderId, :phoneNo, :dob)]; Invalid argument value: java.io.NotSerializableException; nested exception is java.sql.SQLException: Invalid argument value: java.io.NotSerializableException
54092 [http-8084-2] DEBUG org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod  - Method [handleRequest] returned [ModelAndView: reference to view with name 'officer_registration'; model is null]
54092 [http-8084-2] DEBUG org.springframework.web.servlet.DispatcherServlet  - Rendering view [org.springframework.web.servlet.view.JstlView: name 'officer_registration'; URL [/WEB-INF/jsp/officer_registration.jsp]] in DispatcherServlet with name 'crimetrack'

JdbcOfficersDAO

public void saveOfficer(Officers officer) {
    logger.info("In saveOfficer");


    try{            

        String sql= "INSERT INTO crimetrack.tblofficers (userName,password, fName, lName, oName, " +
                    "divisionNo, poisitionId, emailAdd, startDate, endDate, genderId, " +
                    "phoneNo, dob) VALUES (:userName,:password, :fName, :lName, :oName, :divisionNo, "+
                    ":poisitionId, :emailAdd, :startDate, :endDate, :genderId, " +
                    ":phoneNo, :dob)";

        logger.debug("Executing saveOfficer String " + sql);
        int count = getJdbcTemplate().update(sql,new MapSqlParameterSource()
                .addValue("userName",officer.getUserName())
                .addValue("password", officer.getPassword())
                .addValue("fName", officer.getfName())
                .addValue("lName", officer.getlName())
                .addValue("oName", officer.getoName())
                .addValue("divisionNo", officer.getDivisionNo())
                .addValue("positionId",officer.getPositionId())
                .addValue("emailAdd", officer.getEmailAdd())
                .addValue("startDate", officer.getStartDate())
                .addValue("endDate", officer.getEndDate())
                .addValue("genderId", officer.getGenderId())
                .addValue("phoneNo",officer.getPhoneNo())
                .addValue("dob", officer.getDob()));

        logger.info(count +" Rows affected in tblOfficers");



    }catch(Exception e){

        logger.info(e.getMessage());
    }


}

Officers.java

/** * */

import java.util.Date;

public class Officers {

    private String userName;
    private String password;
    private String password2;
    private String fName;
    private String lName;
    private String oName;
    private int divisionNo;
    private int positionId;
    private String emailAdd;
    private Date startDate;
    private Date endDate;
    private String genderId;
    private String phoneNo;
    private Date dob;
    /**
     * No args constructor
     */
    public Officers() {
    }
    /**
     * @param userName
     * @param password
     * @param fName
     * @param lName
     * @param oName
     * @param divisionNo
     * @param positionId
     * @param emailAdd
     * @param startDate
     * @param endDate
     * @param genderId
     * @param phoneNo
     * @param dob
     */
    public Officers(String userName, String password, String fName, String lName,
            String oName, int divisionNo, int positionId, String emailAdd,
            Date startDate, Date endDate, String genderId, String phoneNo,
            Date dob) {
        this.userName = userName;
        this.password = password;
        this.fName = fName;
        this.lName = lName;
        this.oName = oName;
        this.divisionNo = divisionNo;
        this.positionId = positionId;
        this.emailAdd = emailAdd;
        this.startDate = startDate;
        this.endDate = endDate;
        this.genderId = genderId;
        this.phoneNo = phoneNo;
        this.dob = dob;
    }
    /**
     * @return the BadgeNo
     */
    public String getUserName() {
        return userName;
    }
    /**
     * @param badgeNo the BadgeNo to set
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }
    /**
     * @return the Password
     */
    public String getPassword() {
        return password;
    }
    /**
     * @param password the Password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }
    /**
     * @return the First Name
     */
    public String getfName() {
        return fName;
    }
    /**
     * @param fName the First Name to set
     */
    public void setfName(String fName) {
        this.fName = fName;
    }
    /**
     * @return the Last Name
     */
    public String getlName() {
        return lName;
    }
    /**
     * @param lName the Last Name to set
     */
    public void setlName(String lName) {
        this.lName = lName;
    }
    /**
     * @return the Other Name
     */
    public String getoName() {
        return oName;
    }
    /**
     * @param oName the Other Name to set
     */
    public void setoName(String oName) {
        this.oName = oName;
    }
    /**
     * @return the DivisionNo
     */
    public int getDivisionNo() {
        return divisionNo;
    }
    /**
     * @param divisionNo the DivisionNo to set
     */
    public void setDivisionNo(int divisionNo) {
        this.divisionNo = divisionNo;
    }
    /**
     * @return the PositionId
     */
    public int getPositionId() {
        return positionId;
    }
    /**
     * @param positionId the PositionId to set
     */
    public void setPositionId(int positionId) {
        this.positionId = positionId;
    }
    /**
     * @return the Email Address
     */
    public String getEmailAdd() {
        return emailAdd;
    }
    /**
     * @param emailAdd the Email Address to set
     */
    public void setEmailAdd(String emailAdd) {
        this.emailAdd = emailAdd;
    }
    /**
     * @return the Start Date
     */
    public Date getStartDate() {
        return startDate;
    }
    /**
     * @param startDate the Start Date to set
     */
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    /**
     * @return the End Date
     */
    public Date getEndDate() {
        return endDate;
    }
    /**
     * @param endDate the End Date to set
     */
    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }
    /**
     * @return the GenderId
     */
    public String getGenderId() {
        return genderId;
    }
    /**
     * @param genderId the GenderId to set
     */
    public void setGenderId(String genderId) {
        this.genderId = genderId;
    }
    /**
     * @return the Phone Number
     */
    public String getPhoneNo() {
        return phoneNo;
    }
    /**
     * @param phoneNo the Phone Number to set
     */
    public void setPhoneNo(String phoneNo) {
        this.phoneNo = phoneNo;
    }
    /**
     * @return the Date Of Birth
     */
    public Date getDob() {
        return dob;
    }
    /**
     * @param dob the Date Of Birth to set
     */
    public void setDob(Date dob) {
        this.dob = dob;
    }
    /**
     * @return the password2
     */
    public String getPassword2() {
        return password2;
    }
    /**
     * @param password2 the password2 to set
     */
    public void setPassword2(String password2) {
        this.password2 = password2;
    }


}

更新的错误日志

57818 [http-8084-3] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Fetching JDBC Connection from DataSource
57820 [http-8084-3] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Returning JDBC Connection to DataSource
57820 [http-8084-3] DEBUG org.springframework.jdbc.support.SQLErrorCodesFactory  - Database product name cached for DataSource [org.apache.commons.dbcp.BasicDataSource@1077e76]: name is 'MySQL'
57824 [http-8084-3] DEBUG org.springframework.jdbc.support.SQLErrorCodesFactory  - SQL error codes for 'MySQL' found
57825 [http-8084-3] DEBUG org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator  - Unable to translate SQLException with Error code '0', will now try the fallback translator
57825 [http-8084-3] DEBUG org.springframework.jdbc.support.SQLStateSQLExceptionTranslator  - Extracted SQL state class 'S1' from value 'S1009'
57825 [http-8084-3] ERROR com.crimetrack.jdbc.JdbcOfficersDAO  - Could not save officer 
org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [INSERT INTO crimetrack.tblofficers (userName,password, fName, lName, oName, divisionNo, poisitionId, emailAdd, startDate, endDate, genderId, phoneNo, dob) VALUES (:userName,:password, :fName, :lName, :oName, :divisionNo, :poisitionId, :emailAdd, :startDate, :endDate, :genderId, :phoneNo, :dob)]; Invalid argument value: java.io.NotSerializableException; nested exception is java.sql.SQLException: Invalid argument value: java.io.NotSerializableException
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:107)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:603)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:812)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:868)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:876)
    at com.crimetrack.jdbc.JdbcOfficersDAO.saveOfficer(JdbcOfficersDAO.java:113)
    at com.crimetrack.service.OfficerManager.RegisterOfficer(OfficerManager.java:21)
    at com.crimetrack.web.OfficerRegistrationController.handleRequest(OfficerRegistrationController.java:147)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.sql.SQLException: Invalid argument value: java.io.NotSerializableException
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
    at com.mysql.jdbc.PreparedStatement.setSerializableObject(PreparedStatement.java:3359)
    at com.mysql.jdbc.PreparedStatement.setObject(PreparedStatement.java:3010)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.setObject(DelegatingPreparedStatement.java:229)
    at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:351)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:216)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:144)
    at org.springframework.jdbc.core.ArgPreparedStatementSetter.doSetValue(ArgPreparedStatementSetter.java:65)
    at org.springframework.jdbc.core.ArgPreparedStatementSetter.setValues(ArgPreparedStatementSetter.java:46)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:816)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:1)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:587)
    ... 34 more
57826 [http-8084-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod  - Method [handleRequest] returned [ModelAndView: reference to view with name 'officer_registration'; model is null]
57827 [http-8084-3] DEBUG org.springframework.web.servlet.DispatcherServlet  - Rendering view [org.springframework.web.servlet.view.JstlView: name 'officer_registration'; URL [/WEB-INF/jsp/officer_registration.jsp]] in DispatcherServlet with name 'crimetrack'

当你说官员的定义时,你是指XML定义吗?如果是这样,我没有官员的XML定义,我需要创建一个吗?它会是什么样子? - devdar
可能与http://stackoverflow.com/questions/20424989/jdbctemplate-in-search-not-working-properly有关。 - Gray
6个回答

19

您是否正在使用JdbcTemplate(而不是已经被弃用的SimpleJdbcTemplateNamedParameterJdbcTemplate)?

NamedParameterJdbcTemplateSimpleJdbcTemplate才支持命名参数。


3

你好,我遇到了和你一样的问题。

我目前在使用Spring 3.2,看起来在这个版本中,你需要使用NamedParameterJdbcTemplate类而不是JdbcTemplate类。这样做可以解决我的问题。

如果你正在扩展JdbcDaoSupport类,那么请使用NamedParameterJdbcDaoSupport类代替它。在这个类中,你有一个jdbcTemplate和一个NamedParameterJdbcTemplate。


为什么NamedParameterJdbcTemplate可以代替JdbcTemplate?请在您的回答中提供更多信息。 - adamdunson
它对我起作用了,我还必须更改这一行代码。super.jdbcTemplate().update( sqlConsulta , parameterSource); 更改为 super.getNamedParameterJdbcTemplate().update( sqlConsulta , parameterSource); - OJVM

2

尝试向Officers类添加implements Serializable。它目前的所有内容都是可序列化的,如果这是导致问题的类,那么这样做将解决问题。

由于对OP没有帮助,因此添加到响应中,但通常非可序列化异常是由于对象未标记为Serializable引起的。

刚注意到代码中您的sql正在使用'poisitionId',而您的addValue正在使用'positionId'。也许这个不匹配会导致问题?


1
实际上问题并不是字段名称的拼写,因为数据库中的拼写相同。我重新编写了getJdbcTemplate().update("insert into...values(?,?,?...), new object[]{officer.getUserName}"这样的语句,然后它对我起作用了。所以问题在于语句本身。感谢您指出错误,我也进行了修复。 - devdar
Officers类没有被序列化。这是一个内部JDBC模板问题。请参见此处的答案:https://dev59.com/keo6XIcBkEYKwwoYPR_f#14273474 - Gray

1
除了在您的代码块中捕获可能发生的每个异常之外,您只是打印出抛出的异常的消息,因此您丢失了指向异常起源的堆栈跟踪。
由于Spring只会抛出RuntimeException(s),因此您可以删除异常处理并查看堆栈跟踪,它将告诉您更多关于对象不可序列化的信息。作为替代方案,您可以用logger.error("Could not save officer.", e); 替换异常处理中的语句logger.info(e.getMessage());,假设您正在使用log4j。 它将告诉您有关错误的更多信息,而不仅仅是包装异常的消息。
查看您的代码,可能导致此异常的候选者是Officers类。 您是否尝试将其存储在会话中?

0
public class Officers implements Serializable {

1
如果您解释一下为什么您的答案可以解决他们的问题,那么这可能会对提问者有所帮助。 - RobV

0

这个问题的解决是两件事情的结合:

public void saveOfficer(Officers officer) {
        logger.info("In saveOfficer");

        int count = getJdbcTemplate().update("INSERT INTO crimetrack.tblofficers (userName,password, fName, lName, oName, divisionNo, positionId, emailAdd, startDate, endDate, genderId,phoneNo, dob,badgeNo) "+
                                                "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
                                                , new Object[]{officer.getUserName(),StringSecurity.EncryptString(officer.getPassword()),officer.getfName(),
                                                 officer.getlName(),officer.getoName(),officer.getDivisionNo(),officer.getPositionId(),
                                                 officer.getEmailAdd(),officer.getStartDate(),officer.getEndDate(),officer.getGenderId(),
                                                 officer.getPhoneNo(),officer.getDob(),officer.getBadgeNo()});

        logger.info(count +" Rows affected in tblOfficers");            

    }

并且在类中,我按照@Visher的指示进行了包含

public class Officers implements Serializable{  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接