Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧&x2B;冬眠+;石英:动态工作_Java_Spring_Hibernate_Quartz Scheduler - Fatal编程技术网

Java 弹簧&x2B;冬眠+;石英:动态工作

Java 弹簧&x2B;冬眠+;石英:动态工作,java,spring,hibernate,quartz-scheduler,Java,Spring,Hibernate,Quartz Scheduler,我想使用Quartz、Spring和Hibernate动态创建作业。用户与web服务交互以创建此类的工作: public class StartJobSpring extends QuartzJobBean { private String jobId; private String jobType; @Autowired private NoaJobInstancesDAO njiDAO; @Transactional @Override

我想使用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);
    }
}
nojobInstancesDAO是一个简单的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
我不明白为什么! 我在经理课上以这种方式安排工作

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;
}
AutowiringSpringBeanJobFactory类与相同

在我看来,调度程序接线有问题。事实上,我不明白如何检索应用程序上下文

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;
}

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

简短的解决方案:让spring通过工厂完成您的工作

详细解决方案:这里是详细说明。我已通过导入xml配置文件修改了配置文件:

<bean name="complexJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="jobs.StartJob" />
    <property name="durability" value="true" />
</bean>

<bean id="cronTrigger"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="complexJobDetail" />
    <property name="cronExpression" value="0/5 * * ? * SAT-SUN" />
</bean>
我还修改了作业类

@Service
public class StartJob extends QuartzJobBean {

    // the DAO
    private NoaJobInstancesDAO njiDAO;

    public void executeInternal(JobExecutionContext context)
            throws JobExecutionException {
        init(context.getJobDetail().getJobDataMap(), context.getScheduler()
                    .getContext());
        // some logic here
        njiDAO.create(params);
    }

    private void init(JobDataMap jobContextMap,
            SchedulerContext schedulerContext) {
        // some initialization using the job data map, not interesting for DAOs

        // row that inject the correct DAO
        this.njiDAO = (NoaJobInstancesDAO) schedulerContext
                .get("noaJobInstancesDAO");
    }
}

问题解决了

我通过以下操作解决了此问题:

在作业中(必须获得接口):

公共类SchedulerJob扩展了QuartzJobBean{
public void executeInternal(作业执行上下文)
抛出JobExecutionException异常{
试一试{
=((ApplicationContext)context.getJobDetail().getJobDataMap().get(“ApplicationContext”).get(“”);
}捕获(例外e){
e、 printStackTrace();
返回;
}
}
}

在应用程序的.xml上下文中: 还需要在此xml中声明为bean:

<!-- Spring Quartz Scheduler job -->
<bean name="schedulerJob" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="<PATH_OF_YOUR_CLASS_JOB>.SchedulerJob" />
    <property name="applicationContextJobDataKey" value="applicationContext" />
</bean>

<!-- Cron Trigger, run every 10 seconds -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="schedulerJob" />
    <property name="cronExpression" value="0/10 * * * * ?" />
</bean>

<!-- DI -->
<bean id="scheduler"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="jobDetails">
        <list>
            <ref bean="schedulerJob" />
        </list>
    </property>

    <property name="triggers">
        <list>
            <ref bean="cronTrigger" />
        </list>
    </property>
</bean>


我不确定我是否理解了。我用配置bean的主要方法更新了我的问题。我想您的意思是在我的DAO中添加@Autowired注释,并在我的配置中添加另一个bean,该bean注入entityManagerFactory.createEntityManager()。我说的对吗?是的,在DAO层,不是注入EntityManager,而是用自动连线注释注入EntityManager工厂,在方法内部,从EntityManager工厂获取实体管理器。createEntityManager()我会尽快尝试。只是几个问题。第一:我在主线程中也使用DAOs。这种修改会影响我的正常流量吗?第二个:我仍然可以使用createEntityManager()方法忽略事务管理?可以将持久性配置为每个线程上下文(默认配置,这样它不会导致任何并发问题),或者可以将其绑定到应用程序服务器预配置的上下文上,对于代码中的第二个问题,在事务管理器上,您将通过EntityManagerFactory,因此您得到的每个实体管理器都将是spring管理的bean,并将自动启动/结束事务我进行了建议的修改,但我仍然有一个大问题:对DB表的更改不会持久化。但现在实体管理器被正确地看到了。
@Service
public class StartJob extends QuartzJobBean {

    // the DAO
    private NoaJobInstancesDAO njiDAO;

    public void executeInternal(JobExecutionContext context)
            throws JobExecutionException {
        init(context.getJobDetail().getJobDataMap(), context.getScheduler()
                    .getContext());
        // some logic here
        njiDAO.create(params);
    }

    private void init(JobDataMap jobContextMap,
            SchedulerContext schedulerContext) {
        // some initialization using the job data map, not interesting for DAOs

        // row that inject the correct DAO
        this.njiDAO = (NoaJobInstancesDAO) schedulerContext
                .get("noaJobInstancesDAO");
    }
}
public class SchedulerJob extends QuartzJobBean {
public void executeInternal(JobExecutionContext context)
        throws JobExecutionException {
    try{
        <YOUR_BEAN_DAO_INTERFACE_OBJECT> = ((ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext")).get("<YOUR_BEAN_DAO_INTERFACE_ID>");
    } catch (Exception e ){
        e.printStackTrace();
        return;
    }
}
<!-- Spring Quartz Scheduler job -->
<bean name="schedulerJob" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass" value="<PATH_OF_YOUR_CLASS_JOB>.SchedulerJob" />
    <property name="applicationContextJobDataKey" value="applicationContext" />
</bean>

<!-- Cron Trigger, run every 10 seconds -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="schedulerJob" />
    <property name="cronExpression" value="0/10 * * * * ?" />
</bean>

<!-- DI -->
<bean id="scheduler"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="jobDetails">
        <list>
            <ref bean="schedulerJob" />
        </list>
    </property>

    <property name="triggers">
        <list>
            <ref bean="cronTrigger" />
        </list>
    </property>
</bean>