如何在 Spring JPA 中为石英作业运行更新查询 [英] How to run update query in Spring JPA for quartz job

查看:46
本文介绍了如何在 Spring JPA 中为石英作业运行更新查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 spring 4 中有一个quartz 作业,我正在使用 JPA 休眠通过quartz 作业更新数据库值,但是我得到 javax.persistence.TransactionRequiredException: Executing an update/delete query

I have a quartz job in spring 4 and I am using JPA hibernate to update database value through quartz job but I am getting javax.persistence.TransactionRequiredException: Executing an update/delete query

我不明白石英作业中缺少什么样的配置.我提到了 SpringBeanAutowiringSupport 示例仍然更新失败,但选择工作正常.

I don't understand what kind of configuration is missing in quartz job. I referred to SpringBeanAutowiringSupport example still update is failing but select is working fine.

下面是我的代码

@Configuration 
@ComponentScan("com.stock") 
public class QuartzConfiguration {

  @Autowired
  private ApplicationContext applicationContext;

  @Bean
  public JobDetailFactoryBean jobDetailBalanceCarryForward(){
      JobDetailFactoryBean factory = new JobDetailFactoryBean();
      factory.setJobClass(BillingCroneSvcImpl.class);
      Map<String,Object> map = new HashMap<String,Object>();
      map.put("task", "balanceCarryForward");
      factory.setJobDataAsMap(map);
      factory.setGroup("BalanceCarryForwardJob");
      factory.setName("balance carry forward");
      return factory;
  }

  @Bean
  public CronTriggerFactoryBean cronTriggerBalanceCarryForward(){
      CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean();
      stFactory.setJobDetail(jobDetailBalanceCarryForward().getObject());
      stFactory.setStartDelay(3000);
      stFactory.setName("balancCarryForwardTrigger");
      stFactory.setGroup("balanceCarryForwardgroup");
      stFactory.setCronExpression("0 0/1 * 1/1 * ? *");
      return stFactory;
  }

    @Bean
  public SpringBeanJobFactory springBeanJobFactory() {
      AutoWiringSpringBeanJobFactory jobFactory = new    AutoWiringSpringBeanJobFactory();
      jobFactory.setApplicationContext(applicationContext);
      return jobFactory;
}

  @Bean
  public SchedulerFactoryBean schedulerFactoryBean() {
      SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
      schedulerFactory.setJobFactory(springBeanJobFactory());
      schedulerFactory.setTriggers(cronTriggerBalanceCarryForward().getObject());
      return schedulerFactory;
  }
}

在编写quartz executeInternal 方法的类下面

Below class where quartz executeInternal method is written

@Service
@PersistJobDataAfterExecution
@DisallowConcurrentExecution

@Autowired
private BillingCroneRepo billingCroneRepo;

public class BillingCroneSvcImpl extends QuartzJobBean implements BillingCroneSvc  {

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

        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(context);
        billingCroneRepo.updateBalance(); 
        // this method throws exception javax.persistence.TransactionRequiredException: Executing an update/delete query
    }
}

应用配置类

@EnableWebMvc
@EnableTransactionManagement
@Configuration
@ComponentScan({ "com.stock.*" })
@Import({ SecurityConfig.class })
@PropertySource("classpath:jdbc.properties")
public class AppConfig extends WebMvcConfigurerAdapter {

private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";

private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";

@Resource
private Environment env;

@Bean(name = "dataSource")
public DriverManagerDataSource dataSource() {
    DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
    driverManagerDataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
    driverManagerDataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
    driverManagerDataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
    driverManagerDataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
    return driverManagerDataSource;
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setDataSource(dataSource());
    entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);
    entityManagerFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
    entityManagerFactoryBean.setJpaProperties(hibProperties());
    return entityManagerFactoryBean;
}

private Properties hibProperties() {
    Properties properties = new Properties();
    properties.put(PROPERTY_NAME_HIBERNATE_DIALECT,env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
    properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL,env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
    return properties;
}

@Bean
public PlatformTransactionManager transactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
    return transactionManager;
}

@Bean
public ReloadableResourceBundleMessageSource messageSource(){
    ReloadableResourceBundleMessageSource messageSource=new ReloadableResourceBundleMessageSource();
    String[] resources= {"classpath:messages"};
    messageSource.setBasenames(resources);
    return messageSource;
}

@Bean
public LocaleResolver localeResolver() {
    final CookieLocaleResolver ret = new CookieLocaleResolver();
    ret.setDefaultLocale(new Locale("en_IN"));
    return ret;
}

@Bean 
public LocaleChangeInterceptor localeChangeInterceptor(){
    LocaleChangeInterceptor localeChangeInterceptor=new LocaleChangeInterceptor();
    localeChangeInterceptor.setParamName("language");
    return localeChangeInterceptor;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/Angular/**").addResourceLocations("/Angular/");
    registry.addResourceHandler("/css/**").addResourceLocations("/css/");
    registry.addResourceHandler("/email_templates/**").addResourceLocations("/email_templates/");
    registry.addResourceHandler("/fonts/**").addResourceLocations("/fonts/");
    registry.addResourceHandler("/img/**").addResourceLocations("/img/");
    registry.addResourceHandler("/js/**").addResourceLocations("/js/");
    registry.addResourceHandler("/Landing_page/**").addResourceLocations("/Landing_page/");
}

@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
    PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
    org.springframework.core.io.Resource[] resources = new ClassPathResource[] { new ClassPathResource("application.properties") };
    pspc.setLocations(resources);
    pspc.setIgnoreUnresolvablePlaceholders(true);
    return pspc;
}

@Bean
public InternalResourceViewResolver viewResolver() {
    InternalResourceViewResolver viewResolver   = new InternalResourceViewResolver();
    viewResolver.setViewClass(JstlView.class);
    viewResolver.setPrefix("/WEB-INF/pages/");
    viewResolver.setSuffix(".jsp");
    return viewResolver;
}

// through below code we directly read properties file in jsp file
@Bean(name = "propertyConfigurer")
public PropertiesFactoryBean mapper() {
    PropertiesFactoryBean bean = new PropertiesFactoryBean();
    bean.setLocation(new ClassPathResource("application.properties"));
    return bean;
}

}

谁能帮我解决spring JPA中的transational问题

Can anybody please assist me how to resolve transational issue in spring JPA with quartz

推荐答案

感谢大家的帮助.最后我自动装配 EntityManagerFactory 而不是持久性 EntityManager 并且它工作正常.我尝试了所有场景,但没有任何工作可以在石英中注入 spring 事务,所以最后自动生成了 entitymanagerfactory

Thanks you all for your help. Finally I autowired EntityManagerFactory instead of persitance EntityManager and it is working fine. I tried all scenario but nothing worked to inject spring transactional in quartz so finally autoriwed entitymanagerfactory

以下是我的回购类代码.

Below is my repo class code.

@Repository
public class BillingCroneRepoImpl implements BillingCroneRepo {
 /*@PersistenceContext
 private EntityManager entityManager;*/

 @Autowired
 EntityManagerFactory entityManagerFactory;

 public boolean updateTable(){
    EntityManager entityManager =  entityManagerFactory.createEntityManager();
    EntityTransaction entityTransaction = entityManager.getTransaction();
    entityTransaction.begin(); // this will go in try catch
    Query query = entityManager.createQuery(updateSql);
    // update table code goes here

    entityTransaction.commit(); // this will go in try catch
 }
}

这篇关于如何在 Spring JPA 中为石英作业运行更新查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆