今天这个呢,主要是在使用Hibernate的时候遇到过这个问题,想着别人可能也会遇到这个问题,那么就简单的来记录一下问题的产生以及解决方案。
事情的起因是做一个需求,然后测试反馈说这个有个功能报错阻断流程了,让抽时间排查一下,我一开始以为是数据问题,后来我自己环境上尝试了一下,也的确是重现出来这个问题了,而且呢,问题也是相当炸裂的,至于为什么说是相当的炸裂呢?这个后续会说,等到谈到问题的原因时,大家也就自然明白这个问题到时候是有多么的可笑了。
先来简单看一下这个问题的堆栈信息吧,这个堆栈信息不难看出是因为格式不匹配造成的,那么究竟是什么格式呢?之前有了解过的同学可能知道,这种错误最常见的不就是字符串与日期之间转换异常造成的错误吗。而且这个提示也是比较明显的,就是字符串格式转换的有问题,既然知道了可能是时间格式的问题,那么下面就开始自己本地Debug了,尽量定位到离目标代码最近的几行代码中。
Caused by: java.sql.BatchUpdateException: ORA-01861: 文字与格式字符串不匹配
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:12296)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:246)
at weblogic.jdbc.wrapper.PreparedStatement.executeBatch(PreparedStatement.java:216)
at com.p6spy.engine.logging.P6LogPreparedStatement.executeBatch(P6LogPreparedStatement.java:329)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
... 112 more
本地经过Debug之后,问题是在经过查询方法之后才开始报错抛出了这个异常堆栈信息,这时候本人就很懵逼了,这个明显是时间格式不匹配的问题,怎么会在一个find查询方法的时候报错呢?
然后我去问了一下Chatgpt,它给出的答案是这个样子的,跟我预想的基本一致,时间格式的问题。
- 检查插入的日期格式是否与数据库的日期格式一致。如果不一致,则需要将插入的日期格式转换为与数据库一致的格式。
- 检查数据库中日期字段是否为 null。如果是 null,则需要在代码中处理 null 值。
- 检查数据中是否有其他类型的错误,比如字符串转换成数字等。
- 检查是否使用了正确的日期格式化模式。可以查看 Oracle 的日期格式化模式。
- 检查是否正确设置了数据库的时区,以及是否需要转换时区。
看到这里还是没想出来具体为什么会在查询的时候报错了,然后错误日志又翻了翻,上面有一行是这么描述的,说是session update的时候更新有问题,那么这么描述我就理解了,还是实体的某个字段更新有问题,才导致了这种错误。
接下来继续排查问题,这次我就着重看一下那些时间类型的字段有没有什么问题,看了一大圈,没有发现有什么异常啊,这时又很苦恼了,不知如何下手。然后我就想着再Debug看一眼更新之前的参数值哪里有问题,这次呢,终于发现了问题。我看到有个字符串类型的时间,但是这种显然不应该是字符串呀。我就去数据库看了一下表结构,发现这个确实不是字符串类型,而是时间类型,那么这时就定位到了,一个时间类型的字段,你用字符串去赋值,你不报错谁报错呀。关键是实体里确实是字符串类型,有些许的尴尬,排查到了问题我就把字符串类型的时间改了一下,运行程序发现问题解决了,字段赋值正常,问题解决。
这种小的问题,有时候才是最折磨人的,因为一般的惯性思维是想着不会犯这种低级错误的,没想到还是有人这么写了,那么这就很尴尬了,问题解决了。