Spring Batch测试报错:查询BATCH_JOB_EXECUTION版本无结果
在使用Spring Batch测试框架测试应用时,手动在H2数据库创建了测试所需表,但启动Step时触发EmptyResultDataAccessException,错误提示执行SELECT VERSION FROM BATCH_JOB_EXECUTION WHERE JOB_EXECUTION_ID=?返回空结果(预期1条,实际0条)。日志显示已插入BATCH_JOB_INSTANCE和BATCH_JOB_EXECUTION数据,但后续查询无结果。
相关配置及表结构
application-test.properties配置
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'classpath:schema.sql' spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.generate-ddl=true spring.sql.init.mode=always spring.batch.jdbc.initialize-schema=always spring.jpa.defer-datasource-initialization=true spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect spring.jpa.database=h2 spring.datasource.username=sa spring.datasource.password= spring.datasource.driverClassName=org.h2.Driver
schema.sql中BATCH_JOB_INSTANCE表结构
CREATE TABLE BATCH_JOB_INSTANCE ( JOB_INSTANCE_ID BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY , VERSION BIGINT , JOB_NAME VARCHAR(100) NOT NULL, JOB_KEY VARCHAR(32) NOT NULL, constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY) ) ;
问题排查与解决方案
统一表初始化方式
配置中同时启用了spring.sql.init.mode=always、spring.batch.jdbc.initialize-schema=always和Hibernate的create-drop,可能导致表结构被重复创建或覆盖。建议:- 若使用自定义
schema.sql,设置spring.batch.jdbc.initialize-schema=never,避免Spring Batch自动初始化表结构与自定义脚本冲突; - 将
spring.jpa.hibernate.ddl-auto设为none,关闭Hibernate自动创建/删除表的功能,防止覆盖手动配置的表结构。
- 若使用自定义
验证事务与会话一致性
插入BATCH_JOB_EXECUTION的事务可能未提交,导致后续查询在不同会话中无法读取数据:- 在测试类上添加
@Transactional注解,确保所有操作在同一事务内执行; - 确认H2连接URL中的
DB_CLOSE_DELAY=-1已正确配置,避免连接关闭导致内存数据库数据丢失。
- 在测试类上添加
补全BATCH_JOB_EXECUTION表结构
仅提供了BATCH_JOB_INSTANCE表结构,需确保BATCH_JOB_EXECUTION表结构完整(包含JOB_EXECUTION_ID和VERSION字段),标准结构如下:CREATE TABLE BATCH_JOB_EXECUTION ( JOB_EXECUTION_ID BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY , VERSION BIGINT , JOB_INSTANCE_ID BIGINT NOT NULL, CREATE_TIME TIMESTAMP NOT NULL, START_TIME TIMESTAMP DEFAULT NULL, END_TIME TIMESTAMP DEFAULT NULL, STATUS VARCHAR(10), EXIT_CODE VARCHAR(2500), EXIT_MESSAGE VARCHAR(2500), LAST_UPDATED TIMESTAMP, JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL, constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID) references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID) ) ;调整脚本执行顺序
URL中的INIT=RUNSCRIPT与spring.jpa.defer-datasource-initialization=true可能导致脚本执行顺序混乱。建议移除URL中的INIT=RUNSCRIPT,改用spring.sql.init.schema-locations=classpath:schema.sql控制脚本执行顺序,确保Spring Batch表结构先初始化完成。
内容的提问来源于stack exchange,提问作者Jeet_dev

