Spring - Invalid argument value: java.io.NotSerial

2020-07-06 02:45发布

问题:

I am attempting to insert a record into a table and i am getting the following error: I also tried using "?" for the parameters in the sql statement and got the same error.

Error

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;
    }


}

Updated Error Log

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'

回答1:

Are you using JdbcTemplate (instead of SimpleJdbcTemplate which is deprecated) or NamedParameterJdbcTemplate?

Named parameters are only supported in SimpleJdbcTemplate and NamedParameterJdbcTemplate.



回答2:

Hi i was having the same issue that you.

I'm currently using spring 3.2 and it looks like in this version you have to use the class NamedParameterJdbcTemplate instead of the JdbcTemplate. doing this it solve my problem.

if you are extending from JdbcDaoSupport, use NamedParameterJdbcDaoSupport instead of this one. In this class you have both a jdbcTemplate and a NamedParameterJdbcTemplate



回答3:

Try adding implements Serializable to Officers class. Everything in it right now is serializable, and if that's the class that is causing the issue, this will fix it.

Adding to response since didn't help OP, but normally a not serializable exception is caused because the object isn't marked as Serializable.

Just noticed in the code that your sql is using 'poisitionId' but your addValue is using 'positionId'. Perhaps this mismatch is causing your issue?



回答4:

Aside from catching every exception that might occur in your code block you are just printing out the message of the exception that is thrown and so you are loosing the stacktrace that leads you to the origin of your exception.

Since Spring just throws RuntimeException(s) you can remove your exception handling and have a look at the stacktrace which will tell you more about the object not being serializable. As an alternative you can replace the statement logger.info(e.getMessage()); inside your exception handling by logger.error("Could not save officer.", e); assuming you are using log4j. It will tell you more about the error than just the message of the wrapping exception.

Looking at your code a candidate that is causing this exception can be the Officers class. Are you trying to store it in the session?



回答5:

public class Officers implements Serializable {


回答6:

It was a combination of two things that help me solve this issue:

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");            

    }

and on the class i included as @Visher indicated

public class Officers implements Serializable{