Spring Data JPA插入报错:无法将LocalDateTime转为OffsetDateTime
LocalDateTime转OffsetDateTime失败问题分析
场景复现
使用Spring Cloud 2024.0.0搭配PostgreSQL,通过Spring Data JPA和Hibernate操作如下UserError实体类:
@Table(name = "errors") public class UserError { @Id private Integer id; @Column(name = "created_by", insertable = true, updatable = false, nullable = false) @CreatedBy private String createdBy; @Column(name = "created_date", insertable = true, updatable = false, nullable = false) @CreatedDate private OffsetDateTime createdDate; }
插入新记录时抛出以下错误:
org.springframework.dao.InvalidDataAccessApiUsageException: Cannot convert unsupported date type java.time.LocalDateTime to java.time.OffsetDateTime; Supported types are [java.time.LocalDateTime, java.time.LocalDate, java.time.LocalTime, java.time.Instant, java.util.Date, java.lang.Long, long] at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:371) ~[spring-orm-6.2.0.jar:6.2.0] at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246) ~[spring-orm-6.2.0.jar:6.2.0] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:560) ~[spring-orm-6.2.0.jar:6.2.0] at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-6.2.0.jar:6.2.0] at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:343) ~[spring-tx-6.2.0.jar:6.2.0] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:160) ~[spring-tx-6.2.0.jar:6.2.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.0.jar:6.2.0] at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:165) ~[spring-data-jpa-3.4.0.jar:3.4.0]
问题原因
你代码里没手动用LocalDateTime,但Spring Data JPA的审计模块默认行为导致了类型不匹配:
- 当使用
@CreatedDate注解时,Spring的审计自动填充逻辑会自动为该字段生成时间值,默认生成的是LocalDateTime类型。 - 而你的实体类字段定义的是
OffsetDateTime,两者类型不兼容,因此抛出转换异常。
解决方法
方案1:修改实体类字段类型(最简单)
把createdDate字段类型改为LocalDateTime,匹配Spring审计的默认类型:
@Column(name = "created_date", insertable = true, updatable = false, nullable = false) @CreatedDate private LocalDateTime createdDate;
方案2:自定义审计日期生成器(保留OffsetDateTime)
如果必须使用OffsetDateTime,可以自定义Spring审计的日期生成逻辑:
- 实现
DateTimeProvider接口,返回OffsetDateTime:
import org.springframework.data.auditing.DateTimeProvider; import java.time.OffsetDateTime; import java.util.Optional; public class OffsetDateTimeProvider implements DateTimeProvider { @Override public Optional<TemporalAccessor> getNow() { return Optional.of(OffsetDateTime.now()); } }
- 配置该生成器到Spring Boot:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.auditing.DateTimeProvider; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @Configuration @EnableJpaAuditing(dateTimeProviderRef = "offsetDateTimeProvider") public class JpaAuditingConfig { @Bean public DateTimeProvider offsetDateTimeProvider() { return new OffsetDateTimeProvider(); } }
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

