值 '0000-00-00' 不能表示为 java.sql.Date
Posted
技术标签:
【中文标题】值 \'0000-00-00\' 不能表示为 java.sql.Date【英文标题】:Value '0000-00-00' can not be represented as java.sql.Date值 '0000-00-00' 不能表示为 java.sql.Date 【发布时间】:2013-06-16 05:30:57 【问题描述】:我正在做一些需要从数据库中提取数据的项目,我使用 Spring MVC 从数据库中构建模型以选择数据。
这是我的 JSP 页面的问题:
<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>
如您所见,我尝试使用来自Spring
标签库的<form:select>
。问题:但是当它使用这个控制器准备我的模型时:
@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";
它给了我这样的错误:
警告:org.springframework.web.servlet.PageNotFound - 未找到映射 对于 DispatcherServlet 中带有 URI [/controller/] 的 HTTP 请求 name 'appServlet' Hibernate:选择不同的 creationda0_.DATE_ID 作为 DATE1_0_,创建da0_.CHILD_ADMISSION_DATE 为CHILD2_0_, 创建da0_.CHILD_GO_SCHOOL_DATE为CHILD3_0_, creationda0_.PARTICLAR_DATE 作为 PARTICULAR4_0_, creationda0_.VERSION 作为 CREATION_DATE 创建的 VERSION0_ da0_ WARN : org.hibernate.util.JDBCExceptionReporter - SQL 错误:0,SQLState: S1009 错误:org.hibernate.util.JDBCExceptionReporter - 值 '0000-00-00' 不能表示为 java.sql.Date 2013 年 6 月 19 日 下午 3:26:53 org.apache.catalina.core.StandardWrapperValve 调用 严重:servlet [appServlet] 的 Servlet.service() 在上下文中 路径 [/controller] 抛出异常 [请求处理失败;嵌套的 异常是 org.hibernate.exception.GenericJDBCException: could not 执行查询] 根本原因 java.sql.SQLException: Value '0000-00-00' 不能表示为 java.sql.Date
如果您需要我的 Entity 类,我在这里使用来自 java.util
的 Date
,但我使用 @Temporal
注释将其从 SQL 转换为单元 Date
,据我所知:
@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;
假设数据类型转换的问题是因为MVC使用String
,但实际类型是Date
。
【问题讨论】:
好的,谢谢。但它是否只是像“yyyy-MM-dd”一样向我展示它,我也不期待有时间。 @chancea 我希望您不是在暗示 Date 类不能表示 1970 年之前的日期。 @d.v.a 你可以随意格式化它,它只是一个代表毫秒的长值。如果您还需要时间,您应该查看java.sql.timestamp @chancea 毫秒是 64 位长。有足够的位可以追溯到公元前 292000000 年。 How to process 0000-00-00 date in jdbc mysql query的可能重复 【参考方案1】:在 MySql 中'0000-00-00'
被认为是一个有效的日期,但它不能被表示为 java.sql.Date。
如果日期是'0000-00-00'
,您可以使用返回 NULL 的查询,否则返回实际值:
SELECT
CASE WHEN `date`!='0000-00-00' THEN `date` END new_date
FROM
yourtable
或者您可以将以下内容添加到数据源连接字符串中:
zeroDateTimeBehavior=convertToNull
'0000-00-00'
的日期将自动转换为 NULL。
【讨论】:
谢谢。我会尝试,我正在使用休眠,我怎样才能与你的答案相对应。? @ fthiella 感谢您的帮助,我们走在正确的道路上,它生成 0000-00-00 而不是 null 我通过将以下内容添加到我的数据源文件来解决它: zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults =UTF-8 这有帮助。对于那些试图运行应用程序导入一个库来映射 Spring Boot 中 mysql 中的一些表的应用程序,这是由于缺乏命名约定造成的:spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model application.properties 中的 .naming.PhysicalNamingStrategyStandardImpl。 Hibernate 开始,在表中创建了具有空值的新列,因此出现了这个异常。从异常中保存的 convertToNull 但即使是 mysql 表中的有效日期在应用程序中也显示为 null,因为它们来自新的(和空的)列。【参考方案2】:使用 JDBC-mysql 协议附加以下语句:
"?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8"
例如:
jdbc:mysql://localhost/infra?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
【讨论】:
简单优雅!private static String url = "jdbc:mysql://localhost:3306/Your_DB_Name?zeroDateTimeBehavior=convertToNull";
好建议!谢谢!【参考方案3】:
将zeroDateTimeBehavior=convertToNull
添加到 jdbc 连接 URL。
String jdbcUrl="jdbc:mysql://localhost:3306/master_schema?zeroDateTimeBehavior=convertToNull"
【讨论】:
【参考方案4】:这并不总是NULL
问题。您的数据集可能包含格式为05/23/2005
的日期,并且运行加载程序将导致它将0000-00-00
插入到您的日期类型列中。无效的 DATE
、DATETIME
或 TIMESTAMP
值被转换为相应类型的“零”值('0000-00-00' 或 '0000-00-00 00:00:00')(来自MySQL手册)
在使用SELECT
检索时,MySQL 以YYYY-MM-DD'
格式检索'1000-01-01'
到'9999-12-31'
范围内的值。所以你所有的0000-00-00
开始搞砸了。
因此,不仅要注意NULLs
,还要注意 MySQL 不支持的日期格式。
支持 RELAXED 模式,其中任何字符都可以用作分隔符,例如 05/23/2005
中的 /
- 您可能也想尝试一下。
【讨论】:
【参考方案5】:对我来说,以下工作很简单。感谢 @Yogesh H Bhosale 和 @fthiella 在同一个问答线程中的回答,我找到了提示,并对其进行了改进。
代码片段:连接字符串:
private static String CONNECTION_STR = "jdbc:mysql://localhost:3306/water_billing?zeroDateTimeBehavior=convertToNull";
SQL-DB 实现:
为了防止在从返回的数据集中提取数据(日期字段)时出现空指针异常,我将以下代码添加到 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());
注意:请阅读答案中的所有 cmets 以获得良好的理解。
【讨论】:
【参考方案6】:我的猜测是您使用的是 MySQL,您的日期列不是强制性的,因此可以包含 NULL,但 MySQL 会做一些愚蠢的事情,除非您修复 MySQL 服务器设置,否则它将返回 0000-00-00 而不是 NULL。
【讨论】:
啊,我敢打赌这是一个 NULL 问题。 对。只是假设是hibernate和msql之间的一些错误。以上是关于值 '0000-00-00' 不能表示为 java.sql.Date的主要内容,如果未能解决你的问题,请参考以下文章
如何在java中处理具有值“0000-00-00 00:00:00”的日期[重复]
网站搬家之mysql 5.7 date类型默认值不能设置‘0000-00-00’的问题
mysql中datetime类型字段为默认值0000-00-00 00:00:00怎么取出来
报错 java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Tim