0

I am trying to run a function using @Scheduled annotation. Which in turns, call a repository save. But saving is failing with InvalidDataAccessApiUsageException. Posting my stack trace.

org.springframework.dao.InvalidDataAccessApiUsageException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:156)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy87.save(Unknown Source)
    at com.ecsite.web.report.ReportService.saveAttachmentDocument(ReportService.java:495)
    at com.ecsite.web.mail.MailAttachmentProcessor1.processMailAttachment(MailAttachmentProcessor1.java:97)
    at com.ecsite.web.mail.MailAttachmentProcessor1.processTask(MailAttachmentProcessor1.java:59)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
    at com.ecsite.web.audit.AuditService.getContext(AuditService.java:93)
    at com.ecsite.web.entity.BaseEntity.getAuditService(BaseEntity.java:167)
    at com.ecsite.web.entity.BaseEntity.postPersist(BaseEntity.java:181)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.hibernate.ejb.event.BeanCallback.invoke(BeanCallback.java:39)
    at org.hibernate.ejb.event.EntityCallbackHandler.callback(EntityCallbackHandler.java:110)
    at org.hibernate.ejb.event.EntityCallbackHandler.postCreate(EntityCallbackHandler.java:83)
    at org.hibernate.ejb.event.EJB3PostInsertEventListener.onPostInsert(EJB3PostInsertEventListener.java:49)
    at org.hibernate.action.internal.EntityIdentityInsertAction.postInsert(EntityIdentityInsertAction.java:149)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:102)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:214)
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:194)
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:178)
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:321)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
    at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:78)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:208)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:151)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:853)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:827)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:831)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:875)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:257)
    at com.sun.proxy.$Proxy66.persist(Unknown Source)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:358)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:344)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:329)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    ... 25 more

I have added the the "RequestContextListener" in the web.xml. and doing all configurations using java(programatically).

// Class in Which scheduler is called.

@Scheduled(cron = "0 0/5 * 1/1 * *")
public void processTask() {
    saveEntity();
}

//Service

public saveEntity(){
Media media = new Media();
//setting values to media
media = fieldMediaRepository.save(media);
}

//Entity Class

class Media{

    private String property1;
    private String property1;
    private String property1;

    @PostPersist
    public void postPersist() {
        (AuditService)AuditService.getContext().getBean("AuditService");
    }
}

//AuditService Class

class AuditService{
    public static WebApplicationContext getContext() {
        if (context == null) {
            ServletRequestAttributes sessAttributes =
                    (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
            context =
                    WebApplicationContextUtils                            .getWebApplicationContext(sessAttributes.getRequest().getServletContext());
        }
        return context;
    }
}

Showing the trace :

//Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
    at com.ecsite.web.audit.AuditService.getContext(AuditService.java:93)
Benoy Prakash
  • 436
  • 5
  • 17
  • 2
    Post code of class that contains your @Scheduled method. – Sudarshan_SMD Sep 19 '14 at 12:13
  • How can i access the context object, when i am NOT making a request from browser. – Benoy Prakash Sep 20 '14 at 08:22
  • Is the class that contains @Scheduled method a Spring bean? i.e Have your mentioned that class as 'bean' in spring config OR have your mentioned that class as '@Component'? – Sudarshan_SMD Sep 22 '14 at 04:32
  • Service Class containing the _saveEntity()_ funcation is annotated with @Service. Which uses the repository Object _fieldMediaRepository_ , which is an interface extending JpaRepository. – Benoy Prakash Sep 22 '14 at 09:10

2 Answers2

0

The code could be useful, but the stack trace is telling me that you are trying to access to the request with a RequestContextHolder.

The problem here, could be that the RequestContextListener bound the request to the CURRENT thread. And you are trying to access it in other thread (because the Scheduler create other thread).

mondaka
  • 362
  • 3
  • 12
0

It looks like you are running code out of Springs context. Your @Scheduled method does not have access to Repository which is in Spring's context.

Make Class that has your @Scheduled method, Component of Spring. You either make bean entry in your configuration or use @Component annotation for your class. This should do it.

No need to use 'RequestContextListener' in web.xml.

Sudarshan_SMD
  • 2,549
  • 33
  • 23