Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Job run in @Scheduled does not invoke spring data jpa save

I've scheduled a job with annotation @Scheduled, which was supposed to process data and save it to database using spring data jpa. The save method was invoked without any exceptions but there was no insert to database. In the same annotated method I invoked findAll method which worked fine and fetched data. What could be a reason?

@Repository
public interface PossibleOfferLinkRepository extends PagingAndSortingRepository<PossibleOfferLink,   Long> {
}


@Configuration
@ComponentScan
@EnableAutoConfiguration
@Import({Scheduler.class})
@EntityScan(basePackages="model_package")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }


}

@EnableScheduling
@ConditionalOnProperty(value= "property_name")
public class Scheduler {

...
    @Scheduled(fixedRate=100000)
    public void scheduleCrawlerJob() throws MalformedURLException {
            Iterable<PossibleOfferLink> links = repo.findAll();
            PossibleOfferLink link = repo.save(new PossibleOfferLink(new URL("...")));
    }

}

Maven

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.1.8.RELEASE</version>
        </parent>
    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-batch</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <version>1.4.182</version>
            </dependency>
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>${guava.version}</version>
            </dependency>
            <!-- Test -->
            <dependency>
                <groupId>org.easytesting</groupId>
                <artifactId>fest-assert</artifactId>
                <version>${easytesting.version}</version>
            </dependency>
        </dependencies>
like image 352
Maniek Stasz Avatar asked Oct 29 '14 08:10

Maniek Stasz


2 Answers

Finally i solved this issue in this way :

  1. Added @EnableTransactionManagement in Application class and also added PlatformTransactionManager Bean. Check the bellow code:

    @Autowired
    private EntityManagerFactory entityManagerFactory;
    
    @Bean
    public PlatformTransactionManager transactionManager()
    {
        return new JpaTransactionManager(entityManagerFactory);
    }
    

    Here is the imports :

    import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement;

  2. In my scheduler code added bellow code:

    @Scheduled(fixedRate = 60 *10*1000)
    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void reportCurrentTime() {
    doDatabaseTransaction();
    }
    

Here is the imports :

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

Hope this will solve your problem :)

like image 197
Md. Sajedul Karim Avatar answered Nov 20 '22 01:11

Md. Sajedul Karim


Your problem is due to there aren't Transaction in progress to commit.

Cause:

javax.persistence.TransactionRequiredException: no transaction is in progress

Here an example on how to configure transaction manager by annotation. Here the reference

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
      ...
   }

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

}

Add on scheduleCrawlerJob @Transactional

@Scheduled(fixedRate=100000)
@Transactional
public void scheduleCrawlerJob() throws MalformedURLException {
        Iterable<PossibleOfferLink> links = repo.findAll();
        PossibleOfferLink link = repo.save(new PossibleOfferLink(new URL("...")));
}
like image 39
Xstian Avatar answered Nov 20 '22 02:11

Xstian