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
。
我将项目的 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
。