SpringBoot使用Oracle JDBC插入DATE数据报ORA-00932类型不匹配错误
错误原因
直接在JPA实体类中使用Oracle JDBC专属的oracle.sql.DATE作为字段类型是报错的核心原因:
Spring Data JPA的默认ORM实现是Hibernate,Hibernate本身只对JDBC标准规范定义的时间类型做了默认类型映射,识别不了Oracle驱动独有的oracle.sql.DATE类型,会把它当做普通可序列化对象处理,最终生成SQL传参时传入的是BINARY类型的序列化数据,和数据库字段要求的TIMESTAMP类型不匹配,就会抛出ORA-00932错误。
另外你的实体类还存在两个会影响后续运行的问题:
- 构造方法中给不存在的
logEvent字段赋值,实际定义的日志字段名是log - 实体类没有写getter/setter方法,JPA默认情况下无法访问私有字段的值
修复步骤
- 把实体类的时间字段类型从Oracle专属的
oracle.sql.DATE替换为Java标准时间类型,针对你库里TIMESTAMP(6)类型的字段,优先选JDK8+自带的java.time.LocalDateTime,Hibernate 5.2以上版本原生支持这个类型,不需要额外做配置。如果是低版本JDK也可以替换为java.sql.Timestamp。 - 修正实体类构造方法的赋值逻辑,补全所有字段的getter/setter方法。
修正后的LogEntity代码如下:
import java.time.LocalDateTime; import javax.persistence.*; @Entity @Table(name = "T_table1") public class LogEntity{ @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name = "ID") private long id; @Column(name = "LOG") private String log; @Column(name = "CREATED_TIME") private LocalDateTime ts; public LogEntity(){} public LogEntity(String logEvent, LocalDateTime createdAt){ this.ts = createdAt; this.log = logEvent; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getLog() { return log; } public void setLog(String log) { this.log = log; } public LocalDateTime getTs() { return ts; } public void setTs(LocalDateTime ts) { this.ts = ts; } }
- 修改主程序中生成时间对象的逻辑,不再创建Oracle专属DATE对象,直接生成标准LocalDateTime对象:
LocalDateTime th = LocalDateTime.now(); LogService.saveLoggingData(new LogEntity("test log", th));
不推荐为了兼容
oracle.sql.DATE去自定义Hibernate类型转换器,这种写法会让业务代码和Oracle数据库强耦合,后续如果更换数据库或者升级驱动版本会带来额外的适配成本,用JDBC标准的Java时间类型是兼容性最好的方案。
内容的提问来源于stack exchange,提问作者JayEstrera
相关产品推荐
相关产品推荐

