Java 为什么未执行Quartz作业(尽管Quartz表正在使用适当的作业详细信息进行更新)

Java 为什么未执行Quartz作业(尽管Quartz表正在使用适当的作业详细信息进行更新),java,spring,hibernate,quartz-scheduler,Java,Spring,Hibernate,Quartz Scheduler,我正在使用Spring3和Quartz 1.8.6。我在applicationcontext文件中以以下方式定义了SchedulerFactoryBean: <bean id="quartzscheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false"> <property name="autoStartup"> <

我正在使用Spring3和Quartz 1.8.6。我在applicationcontext文件中以以下方式定义了SchedulerFactoryBean:

<bean id="quartzscheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
    <property name="autoStartup">
        <value>true</value>
    </property>
    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
            <prop key="org.quartz.scheduler.instanceName">MyClusteredScheduler</prop>
            <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
            <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
            <prop key="org.quartz.jobStore.isClustered">true</prop>
            <prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
            <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
        </props>
    </property>
    <property name="dataSource">
        <ref bean="quartzdataSource" />
    </property>
</bean>

<bean id="quartzdataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3305/quartz" />
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>
@Entity
@Table(name = "DATABASEMONITOR")
public class DatabaseMonitor implements Serializable, Job {

    @Id
    @GeneratedValue
    @Column(name = "ID", unique = true, nullable = false)
    private Integer id;

    @Column(name = "NAME", nullable = false)
    private String name;

    public DatabaseMonitor(String name, String sqlQuery){
        this.name = name;
        this.sqlQuery = sqlQuery;
    }

    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        System.out.println("inside job");
    }
}
这是我的调度程序控制器类:

public class SchedulerController {

    public static void addJob(DatabaseMonitor databaseMonitor){

        JobDetail job = new JobDetail();
        job.setName(databaseMonitor.getName());
        job.setJobClass(DatabaseMonitor.class);

        CronTrigger trigger = new CronTrigger();
        trigger.setName(databaseMonitor.getName());
        try {
            trigger.setCronExpression("0/2 * * * * ?");
            Scheduler scheduler = (Scheduler) BeansManager.getInstance().getBean("quartzscheduler");
            scheduler.scheduleJob(job, trigger);
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

    }

}
在main类中,我调用此调度函数以在运行时添加作业:

DatabaseMonitor databaseMonitor = new DatabaseMonitor(new Date().toString(), "query string");
        SchedulerController.addJob(databaseMonitor);

现在的问题是,一切工作正常,没有任何异常,作业详细信息在预定义的quartz数据库详细信息中得到更新。但这项工作并没有得到执行。你能帮我一下吗?

你的
数据库监视器应该有一个默认构造函数。Quartz将尝试执行
JobDetail
。而
jobdeail
将从头创建一个
DatabaseMonitor
,并执行其execute方法。由于您的
DatabaseMonitor
没有默认构造函数,因此无法执行它

更新 既然您已经有了一个默认构造函数,我建议您进行一些重构。我正在使用带spring的quartz的2.2.1版本,因此某些类名可能会有所不同

首先让我们把你的实体分成两部分

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

public class DatabaseMonitor {
    @Id
    @GeneratedValue
    @Column(name = "ID", unique = true, nullable = false)
    private Integer id;

    @Column(name = "NAME", nullable = false)
    private String name;

    @Column(name = "SQL_QUERY", nullable = false)
    private String sqlQuery;

    // Getters && Setters && Def. Const etc.
}
我稍后会解释工作部分。让我们将控制器重构为Springbean

import org.quartz.JobDataMap;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.ParseException;

@Component
public class SchedulerController {

    @Autowired
    Scheduler scheduler;

    public void addJob(DatabaseMonitor databaseMonitor) {

        final JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("sqlQuery", databaseMonitor.getSqlQuery());
        final JobDetailImpl jobDetail = new JobDetailImpl();
        jobDetail.setName(databaseMonitor.getName());
        jobDetail.setDurability(true);
        jobDetail.setJobDataMap(jobDataMap);
        jobDetail.setJobClass(DatabaseJob.class);

        try {
            final CronTriggerImpl trigger = new CronTriggerImpl();
            trigger.setCronExpression("0/2 * * * * ?");
            trigger.setName(databaseMonitor.getName());
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (ParseException | SchedulerException e) {
            e.printStackTrace();
        }
    }
}
如您所见,我使用JobDataMap将参数传递给我的作业。此参数可能是sqlQuery。让我们检查一下我们的工作

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.io.Serializable;

public class DatabaseJob implements Job, Serializable {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        final JobDataMap jobDataMap = context.getMergedJobDataMap();
        final String sqlQuery = jobDataMap.getString("sqlQuery");
        System.out.println("SqlQuery: " + sqlQuery);
    }
}
我从上下文中阅读我的查询。我的作业不包含任何状态。在您的实现中,您的作业也是一个实体。Hibernate(或其他JPA实现)代理几乎所有内容,并保存大量状态。这将中断石英执行

更新2
我创建了一个示例应用程序,并将其放入。

您的配置缺少必需配置
org.quartz.threadPool.class
org.quartz.threadPool.threadCount
属性

见:

你能解释一下你想要达到的目标吗?这样,对我来说,这似乎是一个简单的“为什么它不工作”问题。实际上,我尝试的是在运行时从UI添加任务。它可以正常工作,但不会抛出任何异常,但任务永远不会执行:(您是否通过
scheduler::isStarted()检查了调度器是否正在实际运行)
?是的……我正在使用Spring applicationcontext xml中定义的调度程序实例。在检查它是否显示为true之后,即它正在运行,只是为了确保:您是否确实在运行调度程序群集?可能另一台机器正在选择作业,这就是为什么您没有看到异常/输出的原因?它有一个默认构造函数,我忘记了加:(但是它不起作用基于这个答案:预期的输出/结果是否取决于您提供给非默认构造函数的参数?@flo否它不取决于您提供给默认构造函数的参数。但是由于JobDetail将jobClass作为参数,如果您的类没有defaul,则无法初始化对象实例。)t构造函数。@Abhinabyte是否有异常?能否降低quartz的日志级别以调试并检查日志文件以获取更多信息?@bhdrkn我知道;我认为OP可能依赖于添加作业时使用的参数。如果手动创建的调度程序完全正确。SchedulerFactoryBean通过您可以检查的源代码