You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot3.2+Hibernate升级后Postgres存储异常及类型转换报错

问题概述

出现错误:java.lang.ClassCastException: class java.time.LocalDateTime cannot be cast to class [Ljava.lang.Object; (java.time.LocalDateTime and [Ljava.lang.Object; are in module java.base of loader 'bootstrap')

详细背景

将Spring Boot从2.7.x版本升级到3.2版本后,应用无法启动,对某实体字段做了如下修改:

// 旧代码
@Column(name = "last_modified")
@Convert(converter = LocalDateTimeConverter.class)
private LocalDateTime lastModified;

// 新代码
@Column(name = "last_modified")
@JdbcType(BinaryJdbcType.class)
@Convert(converter = LocalDateTimeConverter.class)
private LocalDateTime lastModified;

Postgres中原有last_modified列数据大小为51字节,但修改后新增行的该列大小变为430字节。

使用如下转换器,数据存入数据库前和取出后大小均为51字节,但旧数据读取时引发异常:

@Override
public Byte[] convertToDatabaseColumn(final LocalDateTime localDateTime) {
    log.info("Inside convertToDatabaseColumn");
    if (localDateTime == null) {
        return null;
    }
    try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            final ObjectOutputStream oos = new ObjectOutputStream(buffer)) {
        oos.writeObject(localDateTime);
        log.info("buffer size: {}", buffer.size());
        return ArrayUtils.toObject(buffer.toByteArray());
    } catch (Exception e) {
        // 异常处理省略
    }
}

@Override
public LocalDateTime convertToEntityAttribute(final Byte[] bytes) {
    // 旧数据不会执行此代码,旧数据可正常读取且大小为51字节
    log.info("Inside convertToEntityAttribute: {}", Array.getLength(bytes));
    if (bytes == null) {
        return null;
    }
    try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(ArrayUtils.toPrimitive(bytes));
            final ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream)) {
        final LocalDateTime dateTime = LocalDateTime.parse(objectInputStream.readObject().toString());
        return dateTime;
    } catch (Exception e) {
        // 异常处理省略
    }
}

已尝试的其他方案

方案1

不添加@JdbcType注解时,应用启动失败,报错:
Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Unable to determine SQL type name for column 'last_modified' of table 'resource': class org.hibernate.type.internal.CustomMutabilityConvertedBasicTypeImpl cannot be cast to class org.hibernate.type.BasicPluralType (org.hibernate.type.internal.CustomMutabilityConvertedBasicTypeImpl and org.hibernate.type.BasicPluralType are in unnamed module of loader org.springframework.boot.loader.launch.LaunchedClassLoader @37a71e93)

方案2

尝试添加columnDefinition = "bytea",运行时报错:

@Column(name = "last_modified", columnDefinition = "bytea")
@Convert(converter = LocalDateTimeConverter.class)
private LocalDateTime lastModified;

错误信息:
org.hibernate.exception.SQLGrammarException: could not execute statement [ERROR: column "last_modified" is of type bytea but expression is of type smallint[]"} Hint: You will need to rewrite or cast the expression."}

版本信息

  • org.springframework.boot:spring-boot:3.2.0
  • org.postgresql:postgresql:42.5.4
  • org.hibernate.orm:hibernate-core:6.4.0.Final
  • Java 17

问题总结

  • 新数据可正常写入和读取,但数据库存储大小过大
  • 新旧数据存储大小不同,引发类型转换错误

内容的提问来源于stack exchange,提问作者PSKP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:00:26