SpringBoot 2.6.6中Quartz任务无法触发且无法检索的问题求助
SpringBoot 2.6.6 + Quartz 2.3.2 任务无法触发且getJobDetail抛类型转换异常的解决方案
我之前也碰到过类似的问题,结合你的报错信息和配置来看,核心问题是Quartz在读取JobDetail时,把存储的序列化字节数据当成了long类型解析,导致类型转换失败,进而任务无法正常触发执行。下面给你一步步排查和解决的方案:
一、最可能的原因:Quartz表结构不匹配
你的报错里的\xaced0005是Java对象序列化的魔数,说明某个本该存储数值(long)的字段被存了序列化字节,反过来读取时就会抛出Bad value for type long异常。最常见的场景是qrtz_job_details表的字段类型和Quartz版本不匹配:
解决步骤:
- 获取对应版本的官方建表脚本:
找到Quartz 2.3.2版本的PostgreSQL建表脚本(可以从Maven仓库下载quartz-2.3.2.jar,解压后在org/quartz/impl/jdbcjobstore/tables_postgres.sql路径下找到)。 - 对比现有表结构:
重点检查qrtz_job_details表的JOB_DATA字段,官方脚本里这个字段类型是bytea,如果你的库中这个字段被错误设置为bigint或者其他数值类型,就会导致序列化的JobDataMap字节存入后,读取时解析成long失败。 - 修复表结构:
备份数据后,将错误的字段类型修改为bytea,同时确保其他Quartz相关表的字段类型和官方脚本完全一致。
二、检查JobDataMap的序列化问题
如果表结构没问题,那可能是JobDataMap中的内容导致序列化异常:
- 确保放入JobDataMap的所有对象都实现了
Serializable接口,避免序列化过程中产生异常数据。 - 尽量优先使用基本类型(String、Integer、Long等)存储任务参数,减少复杂对象的序列化,降低存储和解析风险。
三、调整Quartz配置,改用字符串存储JobData
如果不想处理复杂的序列化问题,可以让Quartz用字符串形式存储JobData,避免字节序列化的类型问题:
在你的SpringBoot配置中添加useProperties配置:
spring: quartz: properties: org.quartz.jobStore.useProperties: true org.quartz.threadPool.threadCount: 5 org: quartz: jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
注意:开启这个配置后,JobDataMap只能存储基本类型和String,无法存储自定义对象,需要根据你的业务场景调整。
四、排查Hibernate的影响
你配置了JPA的ddl-auto: validate,Hibernate会验证所有数据库表的结构。如果你的项目中存在Quartz表的实体类(或者Hibernate误验证了Quartz表),可能会导致表结构被意外修改或者验证失败,进而影响Quartz的正常运行:
- 如果不需要Hibernate验证Quartz表,可以修改
ddl-auto为none,或者在Hibernate配置中排除Quartz相关的表。
按照上面的步骤排查后,应该能解决任务无法触发和getJobDetail报错的问题。
内容的提问来源于stack exchange,提问作者Waqar Sadiq
相关产品推荐
相关产品推荐

