Value '0000-00-00' can not be represented as java.sql.Date

半腔热情 提交于 2019-12-17 15:51:59

问题


I'm working on some project which needs to extract data from DB and I use Spring MVC to build model from DB for selecting data.

Here is the problem with my JSP page:

<form action="result" method="get" >
<table>
<thead>
<tr>
<th>Date to select:</th>
<th>Name to select:</th>
<th>Type to select:</th>
</tr>
</thead>

<tbody>
<tr>
<td><form:select  path="listOfDates">
<form:option value="NONE"> --SELECT--</form:option>
<form:options items="${listOfDates}"></form:options>
</form:select>
</td>  
<td><form:select  path="listOfInstitutionsNames">
<form:option value="NONE"> --SELECT--</form:option>
<form:options items="${listOfInstitutionsNames}"></form:options>
</form:select>
</td>
<td>
<form:select  path="listOfInstitutionsTypes">
<form:option value="NONE"> --SELECT--</form:option>
<form:options items="${listOfInstitutionsTypes}"></form:options>
</form:select>
</td>
</tr>
</tbody>

<tfoot>
<tr>
<td><input type="submit" value="Извлечь"/></td>
</tr>
</tfoot>

</table>
</form>

As you can see I try to use <form:select> from Spring tag library.
Question:
but when it's preparing my model with this controller:

@Controller
public class HomeController{ 

    @Autowired
    private ControllerSupportClass controllerSupportClass; 


        @RequestMapping(value="/search", method=RequestMethod.GET)
        public String search(Model model) {
            List<Date> listOfDates = controllerSupportClass.findAllDatesForm();
            List<String> listOfInstitutionsNames = controllerSupportClass.findAllInstitutionsForm();
            List<String> listOfInstitutionsTypes = controllerSupportClass.findAllTypesForm();
            model.addAttribute("listOfInstitutionsTypes", listOfInstitutionsTypes);
            model.addAttribute("listOfInstitutionsNames", listOfInstitutionsNames);
            model.addAttribute("listOfDates", listOfDates);
            return "search";    
        }


        @RequestMapping(value ="/result", method=RequestMethod.GET)
        public String SecondActionPage(@RequestParam String particularDate, 
                                       @RequestParam String nameOfInstitution, 
                                       @RequestParam String typeName,
                                       Model model) throws Exception {


                if(particularDate !="" && nameOfInstitution.trim() !="" && typeName.trim()=="") {                   
                    controllerSupportClass.findWithDateAndName(nameOfInstitution, particularDate, model);                   
                } else if(particularDate.trim() !="" && nameOfInstitution.trim() =="" && typeName.trim() !="") {                    
                    controllerSupportClass.findWithAddedDateAndType(typeName, particularDate, model);                   
                } else if(particularDate.trim() !="" && nameOfInstitution.trim() =="" && typeName.trim() ==""){         
                    controllerSupportClass.findWithAddedDate(particularDate, model);    
                } else if(particularDate.trim() !="" && nameOfInstitution.trim() !="" && typeName.trim() !="") {
                    throw new Exception("Search by choose all parameters is not exceptable");   
                } else {    
                    throw new Exception("You didn't put any search parameters");    
                }           
            return "search";
        }

}

It gives me an error like this:

WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/controller/] in DispatcherServlet with name 'appServlet' Hibernate: select distinct creationda0_.DATE_ID as DATE1_0_, creationda0_.CHILD_ADMISSION_DATE as CHILD2_0_, creationda0_.CHILD_GO_SCHOOL_DATE as CHILD3_0_, creationda0_.PARTICULAR_DATE as PARTICULAR4_0_, creationda0_.VERSION as VERSION0_ from CREATION_DATE creationda0_ WARN : org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: S1009 ERROR: org.hibernate.util.JDBCExceptionReporter - Value '0000-00-00' can not be represented as java.sql.Date Jun 19, 2013 3:26:53 PM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet [appServlet] in context with path [/controller] threw exception [Request processing failed; nested exception is org.hibernate.exception.GenericJDBCException: could not execute query] with root cause java.sql.SQLException: Value '0000-00-00' can not be represented as java.sql.Date

If you need my Entity class it's here I'm using Date from java.util, but I go with @Temporal annotation to convert it from SQL to unit Date as I understand:

@Entity
@Table(name="CREATION_DATE")
public class CreationDate implements Serializable {


    private int dateId;

        @Id
        @GeneratedValue(strategy=IDENTITY)
        @Column(name="DATE_ID")
        public int getDateId() {
            return dateId;
        }

        public void setDateId(int dateId) {
            this.dateId = dateId;
        }


    private int version;

        @Version
        @Column(name="VERSION")
        public int getVersion() {
            return version;
        }

        public void setVersion(int version) {
            this.version = version;
        }


    private Date particularDate;

        @Temporal(TemporalType.DATE)
        @DateTimeFormat(pattern="yyyy-MM-dd")
        @Column(name="PARTICULAR_DATE")
        public Date getParticularDate() {
            return particularDate;
        }

        public void setParticularDate(Date particularDate) {
            this.particularDate = particularDate;
        }


    private Date childGoSchoolDate;

        @Temporal(TemporalType.DATE)
        @DateTimeFormat(pattern="yyyy-MM-dd")
        @Column(name="CHILD_GO_SCHOOL_DATE")
        public Date getChildGoSchoolDate() {
            return childGoSchoolDate;
        }

        public void setChildGoSchoolDate(Date childGoSchoolDate) {
            this.childGoSchoolDate = childGoSchoolDate;
        }


    private Date childAdmissionDate;

        @Temporal(TemporalType.DATE)
        @DateTimeFormat(pattern="yyyy-MM-dd")
        @Column(name="CHILD_ADMISSION_DATE")
        public Date getChildAdmissionDate() {
            return childAdmissionDate;
        }

        public void setChildAdmissionDate(Date childAdmissionDate) {
            this.childAdmissionDate = childAdmissionDate;
        }


}

Assuming that the problem with data type conversion is because MVC uses String, but the actual type is Date.


回答1:


In MySql '0000-00-00' is considered a valid date, but it can't be repesented as java.sql.Date.

You could use a query that returns NULL in case date is '0000-00-00', or the actual value otherwise:

SELECT
  CASE WHEN `date`!='0000-00-00' THEN `date` END new_date
FROM
  yourtable

or you can add to your datasource connection string this:

zeroDateTimeBehavior=convertToNull

and dates as '0000-00-00' will be automatically converted to NULL.




回答2:


Append the following statement with the JDBC-mysql protocol:

"?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8"

for Example:

jdbc:mysql://localhost/infra?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8



回答3:


Add zeroDateTimeBehavior=convertToNull to the jdbc connection URL.

String jdbcUrl="jdbc:mysql://localhost:3306/master_schema?zeroDateTimeBehavior=convertToNull"



回答4:


It is NOT always the NULL issue. Your data set may contain dates in the format 05/23/2005 and running the loader will cause it to insert 0000-00-00 into your DATE type column. Invalid DATE, DATETIME, or TIMESTAMP values are converted to the “zero” value of the appropriate type ('0000-00-00' or '0000-00-00 00:00:00') (from MySQL manual)

While retrieving using a SELECT, MySQL retrieves the value in YYYY-MM-DD' format in the range of '1000-01-01' to '9999-12-31'. So all your 0000-00-00 starts screwing up.

So watch out not just for NULLs but also for date formats not supported by MySQL.

There is RELAXED mode supported where any character can be used as delimiters like / in 05/23/2005 - you may want to try that as well.




回答5:


My wild guess is that you're using MySQL, your date columns are not mandatory and hence can contain NULLs, but MySQL does idiotic things and will return 0000-00-00 instead of NULL unless you fix the MySQL server settings.




回答6:


For me simply the following worked. Thanks to @Yogesh H Bhosale and @fthiella answer in this same Q-A thread I found the hint, and improved it.

Code Snippet:
Connection String:

private static String CONNECTION_STR = "jdbc:mysql://localhost:3306/water_billing?zeroDateTimeBehavior=convertToNull";

SQL-DB implementation:

And to prevent from Null Pointer Exception at the time of data(date field) extraction from the returned data set I add the following code to the Prepared Statement.

Connection conn = DriverManager.getConnection(CONNECTION_STR,USERNAME,PASSWORD);   //   Get connection to the DB to execute the query. You will have to handle exceptions here too..
String SQL = "SELECT dateField FROM my_payments_tbl";
ResultSet rs = conn.createStatement().executeQuery(SQL);
LocalDate prvPaymentDate = null;

while (rs.next())
{
     // Following is the next Important line.
     prvPaymentDate = (rs.getDate(1) != null) ? rs.getDate(1).toLocalDate() : null;    // Checks if it comes as a Null or a Real java.sql.Date object.

     // Depending on the value of the column in the current row, prvPaymentDate could be null.
     // Specially as we instructed via the Connection String, 0000-00-00 00:00:00 will come now as SQL NULL objects.
     // So we filter out them in the above line and assigns null, instead of LocalDate objects.
     if (prvPaymentDate != null)
        System.out.println("date "+prvPaymentDate.toString());
}

Note:
Please read all the comments within the answer for good understanding.



来源:https://stackoverflow.com/questions/17195343/value-0000-00-00-can-not-be-represented-as-java-sql-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!