当前位置: 首页 > 知识库问答 >
问题:

Spring+Hibernate+Quartz:动态作业

壤驷华辉
2023-03-14

我想使用Quartz、Spring和Hibernate创建动态作业。用户与web服务交互以创建此类作业:

public class StartJobSpring extends QuartzJobBean {

    private String jobId;
    private String jobType;

    @Autowired
    private NoaJobInstancesDAO njiDAO;

    @Transactional
    @Override
    protected void executeInternal(JobExecutionContext context)
            throws JobExecutionException {

        JobKey key = context.getJobDetail().getKey();
        JobDataMap dataMap = context.getMergedJobDataMap();

        // some logic
        njiDAO.create(instanceUUID, noaJob.getNoaJob(jobId), jobType);
    }
}

NoaJobInstancesDAO是一个简单的DAO类,它利用了Hibernate的EntityManager:

@Repository
public class NoaJobInstancesDAOHibImpl implements NoaJobInstancesDAO {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @Transactional
    public NoaJobInstanceJPA create(NoaJobInstanceJPA entity) {
        entityManager.persist(entity);
        return entity;
    }

    @Override
    public void create(String instance_uuid, NoaJobJPA job, String job_type) {
        NoaJobInstanceJPA entity = new NoaJobInstanceJPA(instance_uuid, job,
                job_type, "CREATED", null, null, "", "N", "N");
        this.create(entity);
    } 
}

问题是,当这个作业触发时,会抛出一个异常:

javax.persistence.TransactionRequiredException: No transactional EntityManager available

我不明白为什么!在Manager类中,我以这种方式安排作业

JobDetail job = newJob(StartJobSpring.class).withIdentity(//anId)
                .setJobData(//aJobMap).build();
getScheduler().getObject().scheduleJob(job, trigger);

其中排定程序作为

@Autowired
private ApplicationContext applicationContext;

@Bean
SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource, JpaTransactionManager transactionManager) {

    SchedulerFactoryBean bean = new SchedulerFactoryBean();

    AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
    jobFactory.setApplicationContext(applicationContext);
    bean.setJobFactory(jobFactory);

    bean.setTransactionManager(transactionManager);

    return bean;
}

Edit1:应用程序上下文的实例似乎正确。问题不可能在那里。

Edit2:我使用的是单个配置bean(而不是xml文件)。这里的主要方法

@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource   dataSource) {
     LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
     entityManagerFactoryBean.setDataSource(dataSource);
     entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
     entityManagerFactoryBean.setPackagesToScan("package");

    Properties jpaProperties = new Properties();
    jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.OracleDialect");
    jpaProperties.put("hibernate.show_sql", "false");
    jpaProperties.put("hibernate.hbm2ddl.auto", "update");

    entityManagerFactoryBean.setJpaProperties(jpaProperties);

    return entityManagerFactoryBean;
}

@Bean
JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory);
    return transactionManager;
}

@Bean
public NoaJobInstancesDAO noaJobInstancesDAO() {
    NoaJobInstancesDAOHibImpl noaJobInstancesDAO = new NoaJobInstancesDAOHibImpl();
    return noaJobInstancesDAO;
}

共有1个答案

史阳晖
2023-03-14

您处于spring托管上下文中,尝试使用@PersistentContext访问EntityManager,这是一个javax.persistence注释。尝试使用@autowire自动连接EntityManagerFactory bean,我假设您在spring-context.xml中配置了它,并使用EntityManagerFactory.createEntityManager()为您提供spring托管实体管理器,它将由spring包装,并位于您定义的事务管理器中

 类似资料:
  • 我有一个web服务,它对某个作业进行动态调度。job是一个Java类,它扩展了Quartz job接口 我还公开了一个API,它接收一个jobId、cron表达式,并调度一个新的StartJob(它将具有接收到的ID)。下面是我的Spring配置: 我错过了什么?这样的配置正确吗?从工厂中检索到的作业和触发器是同一个类的新实例还是同一个类实例?

  • 我是新的spring批处理框架和石英调度器。我的任务是使用quartz调度器动态调度一个新的spring批处理作业。所有新的spring批处理作业的条目都在我的数据库中,具有触发器表达式。问题是,对于每一个来自数据库的新的spring批处理作业,我们需要将其包装在Quartz的调度器作业中。这就意味着,当有许多spring批处理作业时,就应该有许多批处理作业类来包装它们,并由quartz调度程序运

  • 我有几个spring批处理作业,如果在spring批处理中触发作业执行,这些作业可以正常工作。这些作业将使用JpaItemWriter对数据库进行读写,其中需要事务。 我的问题是,我有一个quartz调度器,它被配置为定期运行这些作业,我得到了“javax.persistence.TransactionRequiredException:无事务正在进行”错误。我知道目前quartz正在实例化作业b

  • 石英2.2 我在运行时动态创建和调度Quartz作业,并将Quartz配置为JDBC-Job-Store。这些作业需要在应用程序执行之间保持不变。在作业执行期间,我需要访问完整的Spring上下文(Spring管理的bean和JPA事务)。 然而,如果我试图将任何东西自动加入到我的工作中,那么我会得到一个错误,比如…“通过字段MyAutowiredField表示的不满足的依赖项” 我想不通。我已经

  • 问题内容: 看来我们使用Quartz-JDBCJobStore以及Spring,Hibernate和Websphere的实现抛出了非托管线程。 我读了一些书,发现IBM的一篇技术文章指出将Quartz与Spring结合使用会导致这种情况。他们提出使用CommnonJ解决此问题的建议。 我进行了一些进一步的研究,到目前为止,我所看到的唯一示例都处理了不在数据库中的旧JobStore计划。 因此,我想