org.hsqldb.HsqlException: 升级 spring 引导版本时用户缺少权限或找不到对象

org.hsqldb.HsqlException: user lacks privilege or object not found when upgrading spring boot version

我将项目的 spring 引导版本从 2.4.2 升级到 2.5.6,现在工作单元测试无法正常工作,出现 org.hsqldb.HsqlException: user lacks privilege or object not found 异常。我有 SchedulerConfig class 及其测试 class:

调度器配置:

package com.nuance.powershare.email.scheduler;

import java.util.Properties;
import javax.sql.DataSource;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

/**
 * Spring configuration for quartz scheduler.
 */
@Configuration
public class SchedulerConfig {

    private static final String JOB_DESC = "Job to update email blacklist";
    private static final String GROUP = "EmailBlacklistScheduler";
    @Value("${scheduler.emailBlacklist.cron}")
    private String emailBlacklistTrigger;
    @Value("${scheduler.name}")
    private String schedulerName;

    /**
     * @return register application context helper bean in context
     */
    @Bean
    public ApplicationContextHelper applicationContextHelper() {
        return new ApplicationContextHelper();
    }

    /**
     * @param dataSource datasource
     * @param transactionManager transaction manager
     * @return quartz scheduler bean
     */
    @Bean
    public SchedulerFactoryBean scheduler(final DataSource dataSource,
        final PlatformTransactionManager transactionManager) {
        SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
        scheduler.setSchedulerName(this.schedulerName);
        scheduler.setOverwriteExistingJobs(true);
        scheduler.setDataSource(dataSource);
        scheduler.setTransactionManager(transactionManager);
        scheduler.setQuartzProperties(quartzProperties());
        scheduler.setTriggers(schedulerTriggers());
        scheduler.setJobDetails(schedulerJobs());
        return scheduler;
    }

    /**
     * @return loads quartz properties
     */
    @Bean
    @ConfigurationProperties("scheduler")
    public Properties quartzProperties() {
        return new Properties();
    }

    /**
     * @return triggers
     */
    @Bean
    public Trigger[] schedulerTriggers() {
        return new Trigger[] { schedulerUpdaterTrigger().getObject() };
    }

    /**
     * @return jobs
     */
    @Bean
    public JobDetail[] schedulerJobs() {
        return new JobDetail[] { schedulerUpdaterJob().getObject() };
    }

    /**
     * @return the job detail factory bean
     */
    @Bean
    public JobDetailFactoryBean schedulerUpdaterJob() {
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(SmtpStatusScheduler.class);
        jobDetailFactoryBean.setName(SmtpStatusScheduler.class.getSimpleName());
        jobDetailFactoryBean.setDescription(JOB_DESC);
        jobDetailFactoryBean.setGroup(GROUP);
        jobDetailFactoryBean.setDurability(true);
        return jobDetailFactoryBean;
    }

    /**
     * @return the cron trigger factory bean
     */
    @Bean
    public CronTriggerFactoryBean schedulerUpdaterTrigger() {
        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
        cronTriggerFactoryBean.setJobDetail(schedulerUpdaterJob().getObject());
        cronTriggerFactoryBean.setCronExpression(emailBlacklistTrigger);
        return cronTriggerFactoryBean;
    }
}

调度器配置测试:

package com.nuance.powershare.email.scheduler;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertNotNull;

/**
 * Tests for {@link SchedulerConfig}.
 */
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { SchedulerConfig.class, DataSourceAutoConfiguration.class,
    DataSourceTransactionManagerAutoConfiguration.class })
@TestPropertySource("classpath:application.properties")
public class SchedulerConfigTest {

    @Autowired
    private ApplicationContextHelper applicationContextHelper;
    @Autowired
    private SchedulerFactoryBean scheduler;
    @Autowired
    private Trigger[] schedulerTriggers;
    @Autowired
    private JobDetail[] schedulerJobs;

    @Test
    public void applicationContextHelper() {
        assertNotNull(applicationContextHelper);
    }

    @Test
    public void scheduler() {
        assertNotNull(scheduler);
    }

    @Test
    public void schedulerTriggers() {
        assertNotNull(schedulerTriggers);
    }

    @Test
    public void schedulerJobs() {
        assertNotNull(schedulerJobs);
    }
}

application.properties:

# ===================================
# Application Custom properties
# ===================================
smtp.apiKey=apiKey
smtp.url=https://api.smtp2go.com/emails
smtp.username=laura.evans@nuance.com
smtp.limit=5
smtp.bounce.max.tries=5

#==========================
# Hibernate
#==========================
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy
# Hibernate ddl auto (validate, create, create-drop, update)
spring.jpa.hibernate.ddl-auto=none


# ===============================
# = DATA SOURCE
# Set here configurations for the database connection
# ===============================
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.hsqldb.jdbc.JDBCDriver
spring.datasource.remove-abandoned=true
spring.datasource.remove-abandoned-timeout=600
spring.datasource.initial-size=2
spring.datasource.max-active=8
spring.datasource.min-idle=0
spring.datasource.max-idle=2
spring.datasource.max-wait=30000
spring.datasource.test-while-idle=true
# ===============================
# Quartz Scheduler
# ===============================
scheduler.name=TestScheduler
scheduler.emailBlacklist.cron=0 0/2 * * * ?
scheduler.org.quartz.scheduler.name=TestScheduler
scheduler.org.quartz.scheduler.instanceId=AUTO
scheduler.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
scheduler.org.quartz.threadPool.threadCount=10
scheduler.org.quartz.threadPool.threadPriority=5
scheduler.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreCMT
scheduler.org.quartz.jobStore.misfireThreshold=60000
scheduler.org.quartz.jobStore.isClustered=true
scheduler.org.quartz.jobStore.clusterCheckinInterval=15000
scheduler.org.quartz.jobStore.tablePrefix=QRTZ_
scheduler.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate
scheduler.org.quartz.jobStore.useProperties=false

schema.sql:

SET DATABASE SQL SYNTAX MSS TRUE;

------------------------------------------------------------------
-- SCHEDULE ID SEQUENCE
------------------------------------------------------------------
CREATE SEQUENCE SCHEDULE_ID_SEQ START
WITH 1
INCREMENT BY 1;
------------------------------------------------------------------
-- SCHEDULE TABLE
------------------------------------------------------------------
DROP TABLE SCHEDULE
if EXISTS ;
CREATE TABLE SCHEDULE(
SCHEDULE_ID   BIGINT GENERATED BY DEFAULT AS SEQUENCE SCHEDULE_ID_SEQ PRIMARY KEY,
  START_TIME    DATETIME NOT NULL,
  END_TIME      DATETIME NOT NULL,
  STATUS        VARCHAR(20)  NOT NULL,
  PROCESSED_BY  VARCHAR(100),
  UPDATED_ON    DATETIME DEFAULT SYSDATE NOT NULL,
  CREATED_ON    DATETIME DEFAULT SYSDATE NOT NULL
);

------------------------------------------------------------------
-- EMAIL BLACKLIST ID SEQUENCE
------------------------------------------------------------------
CREATE SEQUENCE EMAIL_BLACKLIST_ID_SEQ START
WITH 1
INCREMENT BY 1;
------------------------------------------------------------------
-- EMAIL_BLACKLIST TABLE
------------------------------------------------------------------
DROP TABLE EMAIL_BLACKLIST
if EXISTS ;
                                 
CREATE TABLE EMAIL_BLACKLIST(
ID                INT GENERATED BY DEFAULT AS SEQUENCE EMAIL_BLACKLIST_ID_SEQ PRIMARY KEY,
  EMAIL             VARCHAR(320) NOT NULL,
  REOCCURANCE_COUNT TINYINT   DEFAULT 0 NOT NULL,
  BLACKLISTED       CHAR(1) DEFAULT '0' NOT NULL,
  CREATED_ON        DATETIME DEFAULT SYSDATE NOT NULL,
  UPDATED_ON        DATETIME DEFAULT SYSDATE NOT NULL
);

------------------------------------------------------------------
-- QUARTZ SCHEDULER TABLES
------------------------------------------------------------------
DROP TABLE qrtz_locks
IF EXISTS ;
DROP TABLE qrtz_scheduler_state
IF EXISTS ;
DROP TABLE qrtz_fired_triggers
IF EXISTS ;
DROP TABLE qrtz_paused_trigger_grps
IF EXISTS ;
DROP TABLE qrtz_calendars
IF EXISTS ;
DROP TABLE qrtz_blob_triggers
IF EXISTS ;
DROP TABLE qrtz_cron_triggers
IF EXISTS ;
DROP TABLE qrtz_simple_triggers
IF EXISTS ;
DROP TABLE qrtz_simprop_triggers
IF EXISTS ;
DROP TABLE qrtz_triggers
IF EXISTS ;
DROP TABLE QRTZ_JOB_DETAILS
IF EXISTS ;

CREATE TABLE QRTZ_JOB_DETAILS
(
  SCHED_NAME        VARCHAR(120) NOT NULL,
  JOB_NAME          VARCHAR(200) NOT NULL,
  JOB_GROUP         VARCHAR(200) NOT NULL,
  DESCRIPTION       VARCHAR(250) NULL,
  JOB_CLASS_NAME    VARCHAR(250) NOT NULL,
  IS_DURABLE        BOOLEAN NOT NULL,
  IS_NONCONCURRENT  BOOLEAN NOT NULL,
  IS_UPDATE_DATA    BOOLEAN NOT NULL,
  REQUESTS_RECOVERY BOOLEAN NOT NULL,
  JOB_DATA          BLOB NULL,
PRIMARY KEY(SCHED_NAME, JOB_NAME, JOB_GROUP)
);

CREATE TABLE qrtz_triggers
(
  SCHED_NAME     VARCHAR(120) NOT NULL,
  TRIGGER_NAME   VARCHAR(200) NOT NULL,
  TRIGGER_GROUP  VARCHAR(200) NOT NULL,
  JOB_NAME       VARCHAR(200) NOT NULL,
  JOB_GROUP      VARCHAR(200) NOT NULL,
  DESCRIPTION    VARCHAR(250) NULL,
  NEXT_FIRE_TIME NUMERIC(13)NULL,
PREV_FIRE_TIME NUMERIC(13)NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16)NOT NULL,
TRIGGER_TYPE VARCHAR(8)NOT NULL,
START_TIME NUMERIC(13)NOT NULL,
END_TIME NUMERIC(13)NULL,
CALENDAR_NAME VARCHAR(200)NULL,
MISFIRE_INSTR NUMERIC(2)NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY(SCHED_NAME, JOB_NAME, JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME, JOB_NAME, JOB_GROUP)
);

CREATE TABLE qrtz_simple_triggers
(
  SCHED_NAME    VARCHAR(120) NOT NULL,
  TRIGGER_NAME  VARCHAR(200) NOT NULL,
  TRIGGER_GROUP VARCHAR(200) NOT NULL,
  REPEAT_COUNT  NUMERIC(7)NOT NULL,
REPEAT_INTERVAL NUMERIC(12)NOT NULL,
TIMES_TRIGGERED NUMERIC(10)NOT NULL,
PRIMARY KEY(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
);

CREATE TABLE qrtz_cron_triggers
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
);

CREATE TABLE qrtz_simprop_triggers
(
  SCHED_NAME    VARCHAR(120) NOT NULL,
  TRIGGER_NAME  VARCHAR(200) NOT NULL,
  TRIGGER_GROUP VARCHAR(200) NOT NULL,
  STR_PROP_1    VARCHAR(512) NULL,
  STR_PROP_2    VARCHAR(512) NULL,
  STR_PROP_3    VARCHAR(512) NULL,
  INT_PROP_1    NUMERIC(9)NULL,
INT_PROP_2 NUMERIC(9)NULL,
LONG_PROP_1 NUMERIC(13)NULL,
LONG_PROP_2 NUMERIC(13)NULL,
DEC_PROP_1 NUMERIC(13, 4)NULL,
DEC_PROP_2 NUMERIC(13, 4)NULL,
BOOL_PROP_1 BOOLEAN NULL,
BOOL_PROP_2 BOOLEAN NULL,
PRIMARY KEY(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
);

CREATE TABLE qrtz_blob_triggers
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
);

CREATE TABLE qrtz_calendars
(
  SCHED_NAME    VARCHAR(120) NOT NULL,
  CALENDAR_NAME VARCHAR(200) NOT NULL,
  CALENDAR      BLOB NOT NULL,
PRIMARY KEY(SCHED_NAME, CALENDAR_NAME)
);

CREATE TABLE qrtz_paused_trigger_grps
(
  SCHED_NAME    VARCHAR(120) NOT NULL,
  TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY(SCHED_NAME, TRIGGER_GROUP)
);

CREATE TABLE qrtz_fired_triggers
(
  SCHED_NAME    VARCHAR(120) NOT NULL,
  ENTRY_ID      VARCHAR(95) NOT NULL,
  TRIGGER_NAME  VARCHAR(200) NOT NULL,
  TRIGGER_GROUP VARCHAR(200) NOT NULL,
  INSTANCE_NAME VARCHAR(200) NOT NULL,
  FIRED_TIME    NUMERIC(13)NOT NULL,
SCHED_TIME NUMERIC(13)NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16)NOT NULL,
JOB_NAME VARCHAR(200)NULL,
JOB_GROUP VARCHAR(200)NULL,
IS_NONCONCURRENT BOOLEAN NULL,
REQUESTS_RECOVERY BOOLEAN NULL,
PRIMARY KEY(SCHED_NAME, ENTRY_ID)
);

CREATE TABLE qrtz_scheduler_state
(
  SCHED_NAME        VARCHAR(120) NOT NULL,
  INSTANCE_NAME     VARCHAR(200) NOT NULL,
  LAST_CHECKIN_TIME NUMERIC(13)NOT NULL,
CHECKIN_INTERVAL NUMERIC(13)NOT NULL,
PRIMARY KEY(SCHED_NAME, INSTANCE_NAME)
);

CREATE TABLE qrtz_locks
(
  SCHED_NAME VARCHAR(120) NOT NULL,
  LOCK_NAME  VARCHAR(40) NOT NULL,
PRIMARY KEY(SCHED_NAME, LOCK_NAME)
);

错误:


java.lang.IllegalStateException: Failed to load ApplicationContext

    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access0(ParentRunner.java:66)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:293)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scheduler' defined in com.nuance.powershare.email.scheduler.SchedulerConfig: Invocation of init method failed; nested exception is org.quartz.JobPersistenceException: Couldn't determine job existence (EmailBlacklistScheduler.SmtpStatusScheduler): user lacks privilege or object not found: QRTZ_JOB_DETAILS in statement [SELECT JOB_NAME FROM QRTZ_JOB_DETAILS WHERE SCHED_NAME = 'TestScheduler' AND JOB_NAME = ? AND JOB_GROUP = ?] [See nested exception: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: QRTZ_JOB_DETAILS in statement [SELECT JOB_NAME FROM QRTZ_JOB_DETAILS WHERE SCHED_NAME = 'TestScheduler' AND JOB_NAME = ? AND JOB_GROUP = ?]]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=16=](AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:925)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:127)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:275)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:243)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    ... 25 more
Caused by: org.quartz.JobPersistenceException: Couldn't determine job existence (EmailBlacklistScheduler.SmtpStatusScheduler): user lacks privilege or object not found: QRTZ_JOB_DETAILS in statement [SELECT JOB_NAME FROM QRTZ_JOB_DETAILS WHERE SCHED_NAME = 'TestScheduler' AND JOB_NAME = ? AND JOB_GROUP = ?] [See nested exception: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: QRTZ_JOB_DETAILS in statement [SELECT JOB_NAME FROM QRTZ_JOB_DETAILS WHERE SCHED_NAME = 'TestScheduler' AND JOB_NAME = ? AND JOB_GROUP = ?]]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.jobExists(JobStoreSupport.java:1137)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJob(JobStoreSupport.java:1109)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeVoid(JobStoreSupport.java:1095)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3780)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3778)
    at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:245)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJob(JobStoreSupport.java:1091)
    at org.quartz.core.QuartzScheduler.addJob(QuartzScheduler.java:938)
    at org.quartz.core.QuartzScheduler.addJob(QuartzScheduler.java:927)
    at org.quartz.impl.StdScheduler.addJob(StdScheduler.java:268)
    at org.springframework.scheduling.quartz.SchedulerAccessor.addJobToScheduler(SchedulerAccessor.java:283)
    at org.springframework.scheduling.quartz.SchedulerAccessor.registerJobsAndTriggers(SchedulerAccessor.java:225)
    at org.springframework.scheduling.quartz.SchedulerFactoryBean.afterPropertiesSet(SchedulerFactoryBean.java:505)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
    ... 40 more
Caused by: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: QRTZ_JOB_DETAILS in statement [SELECT JOB_NAME FROM QRTZ_JOB_DETAILS WHERE SCHED_NAME = 'TestScheduler' AND JOB_NAME = ? AND JOB_GROUP = ?]
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
    at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
    at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337)
    at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.quartz.impl.jdbcjobstore.AttributeRestoringConnectionInvocationHandler.invoke(AttributeRestoringConnectionInvocationHandler.java:73)
    at com.sun.proxy.$Proxy35.prepareStatement(Unknown Source)
    at org.quartz.impl.jdbcjobstore.StdJDBCDelegate.jobExists(StdJDBCDelegate.java:773)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.jobExists(JobStoreSupport.java:1135)
    ... 54 more
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: QRTZ_JOB_DETAILS
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.ParserDQL.readTableName(Unknown Source)
    at org.hsqldb.ParserDQL.readTableOrSubquery(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableReference(Unknown Source)
    at org.hsqldb.ParserDQL.XreadFromClause(Unknown Source)
    at org.hsqldb.ParserDQL.XreadTableExpression(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQuerySpecification(Unknown Source)
    at org.hsqldb.ParserDQL.XreadSimpleTable(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryPrimary(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryTerm(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryExpressionBody(Unknown Source)
    at org.hsqldb.ParserDQL.XreadQueryExpression(Unknown Source)
    at org.hsqldb.ParserDQL.compileCursorSpecification(Unknown Source)
    at org.hsqldb.ParserCommand.compilePart(Unknown Source)
    at org.hsqldb.ParserCommand.compileStatement(Unknown Source)
    at org.hsqldb.Session.compileStatement(Unknown Source)
    at org.hsqldb.StatementManager.compile(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    ... 66 more


我做错了什么?发生了什么变化?我不确定我应该朝哪个方向走.. 任何帮助将不胜感激。

编辑:从进一步调查来看,似乎 scheduler bean 有问题。

我在 ScheduledConfigTest 中修复它的方式是这样的:

package com.nuance.powershare.email.scheduler;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.assertNotNull;

/**
 * Tests for {@link SchedulerConfig}.
 */
@RunWith(SpringRunner.class)
@DataJpaTest
@Import(SchedulerConfig.class)
@TestPropertySource("classpath:application.properties")
public class SchedulerConfigTest {

    @Autowired
    private ApplicationContextHelper applicationContextHelper;
    @Autowired
    private SchedulerFactoryBean scheduler;
    @Autowired
    private Trigger[] schedulerTriggers;
    @Autowired
    private JobDetail[] schedulerJobs;

    @Test
    public void applicationContextHelper() {
        assertNotNull(applicationContextHelper);
    }

    @Test
    public void scheduler() {
        assertNotNull(scheduler);
    }

    @Test
    public void schedulerTriggers() {
        assertNotNull(schedulerTriggers);
    }

    @Test
    public void schedulerJobs() {
        assertNotNull(schedulerJobs);
    }
}

我删除了 @ContextConfiguration 并添加了 @DataJpaTest@Import