Spring Boot读取MySQL TIME类型超23:59:59报错如何解决?
问题根因
MySQL的TIME类型设计上支持存储-838:59:59到838:59:59区间的时长值,并非仅支持24小时内的时钟时间;但JDBC规范中的LocalTime、java.sql.Time类型均对应单日的时钟时间,最大值仅到23:59:59,因此读取超过该范围的TIME值时就会抛出转换异常。
可行解决方案
方案1:字符串接收后手动转时长(最简便,无额外依赖)
这也是报错日志中官方推荐的方案,你之前尝试String类型不生效大概率是后续转换逻辑有误,完整实现如下:
- 修改Repository层返回值为String
@Query(value = "SELECT total_hours FROM tasks WHERE id=:taskId", nativeQuery = true) String findbytaskid(@Param("taskId") Integer taskId);
- 业务层将拿到的HH:mm:ss格式字符串转换为
java.time.Duration进行运算
// 从数据库拿到字符串值,比如"30:00:00" String timeStr = repository.findbytaskid(timeSheet.getTaskId()); // 转换为Duration String[] parts = timeStr.split(":"); long hours = Long.parseLong(parts[0]); long minutes = Long.parseLong(parts[1]); long seconds = Long.parseLong(parts[2]); Duration totalDuration = Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds); // 后续直接用Duration做业务运算,比如获取总秒数:totalDuration.getSeconds()
方案2:自定义JPA转换器实现自动转换
如果需要多处读取该字段,可实现JPA属性转换器,避免重复写转换逻辑:
- 自定义转换器类
import javax.persistence.AttributeConverter; import javax.persistence.Converter; import java.time.Duration; @Converter(autoApply = true) public class MySQLTimeDurationConverter implements AttributeConverter<Duration, String> { @Override public String convertToDatabaseColumn(Duration duration) { // 存储时的转换逻辑,如果需要写回数据库可实现 long seconds = duration.getSeconds(); long hours = seconds / 3600; long minutes = (seconds % 3600) / 60; long sec = seconds % 60; return String.format("%d:%02d:%02d", hours, minutes, sec); } @Override public Duration convertToEntityAttribute(String timeStr) { String[] parts = timeStr.split(":"); long hours = Long.parseLong(parts[0]); long minutes = Long.parseLong(parts[1]); long seconds = Long.parseLong(parts[2]); return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds); } }
- 修改实体类对应字段的类型为Duration即可,JPA会自动完成转换
@Column(name = "total_hours") private Duration totalHours;
方案3:调整数据库字段类型(根源解决)
如果业务允许调整表结构,建议将该字段改为INT类型存储总秒数/总分钟数,或者改为VARCHAR类型直接存时长字符串,从根源上避免数据库类型和Java类型不匹配的问题。
内容的提问来源于stack exchange,提问作者user15958535
相关产品推荐
相关产品推荐

