728x90
반응형
728x90
반응형
728x90
반응형

@Scheduled로 jpa repository의 save 를 이용하는 경우에 발생되었습니다.

 

정확히 문제가 된 부분은 아래 부분인데, 해당 부분에서 세션의 정보를 가져와 작성자를 쓰려고 했던게 문제입니다.

스케줄에 의해 진행되므로 세션이 없죠.

at packageName.core.model.entity.base.BaseModel.preUpdate(BaseModel.java:87)

 

그래서에 해당되는 부분의 save를 사용하지 않고 nativeQuery를 작성하여 처리하도록 변경하였습니다.

(세션정보를 가져오지 않도록 함)

at packageName.core.schedule.service.ScheduleService.removeAttachFileInServer(ScheduleService.java:42)

 

* 참고정보

 

자바에러-no thread-bound request found are you referring to request attributes outside of an actual web

제목이 좀 길다. 내가 겪었던 오류이다. no thread-bound request found are you referring to request att...

blog.naver.com

 

* 에러 전문

20210621 18:40:23.854 [scheduling-1] ERROR o.s.s.s.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task

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: 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: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:371)

at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:235)

at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:566)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)

at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)

at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407)

at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)

at com.sun.proxy.$Proxy112.save(Unknown Source)

at packageName.core.schedule.service.ScheduleService.removeAttachFileInServer(ScheduleService.java:42)

at packageName.core.schedule.ScheduleCron.job_60min(ScheduleCron.java:63)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)

at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)

at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.util.concurrent.FutureTask.runAndReset(Unknown Source)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)

at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

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: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)

at packageName.core.common.utils.SessionUtil.getSession(SessionUtil.java:22)

at packageName.core.model.entity.base.BaseModel.preUpdate(BaseModel.java:87)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.hibernate.jpa.event.internal.EntityCallback.performCallback(EntityCallback.java:32)

at org.hibernate.jpa.event.internal.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:95)

at org.hibernate.jpa.event.internal.CallbackRegistryImpl.preUpdate(CallbackRegistryImpl.java:69)

at org.hibernate.event.internal.DefaultFlushEntityEventListener.invokeInterceptor(DefaultFlushEntityEventListener.java:368)

at org.hibernate.event.internal.DefaultFlushEntityEventListener.handleInterception(DefaultFlushEntityEventListener.java:350)

at org.hibernate.event.internal.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:301)

at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:172)

at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93)

at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:230)

at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:93)

at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)

at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:93)

at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362)

at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453)

at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212)

at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380)

at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)

at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)

at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)

at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)

at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)

at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562)

... 29 common frames omitted

 

 

 

 

728x90
반응형
728x90
반응형

컨트롤러와 관계 없이 jpa의 entity @PrePersist, @PreUpdate에서 바로 세션 정보를 꺼내고 싶었다.

그러나 지식이 짧은 관계로 방법을 몰랐는데 찾아서 간단히 기록을 남긴다.

 

1. 로그인 세션 기록

1
2
3
4
5
6
7
8
9
10
11
@PostMapping(value = "/login")
public RestResponse<Member> loginProcess(@RequestBody LoginReqDTO reqDTO, HttpServletRequest request) throws Exception {
    // 로그인 계정의 정보 조회        
    Member memberinfo = serviceClass.checkLogin(reqDTO);
    
    if (memberinfo != null && memberinfo.getMemSeq() != null && memberinfo.getMemSeq() > 0) {
        // 세션에 로그인 계정정보 기록
        request.getSession().setAttribute("memberinfo", memberinfo);
    }    
    return new RestResponse<>(memberinfo);
}
cs

8번 라인의 "memberinfo"으로 세션에 로그인 계정정보 기록!

 

2. 세션 정보를 얻기 위한 유틸

1
2
3
4
5
6
public class SessionUtil {
    public static HttpSession getSession() {
        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        return attr.getRequest().getSession();
    }
}
cs

3. entity의 @PrePersist, @PreUpdate에서 세션에 기록된 접속자의 정보 습득

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@PrePersist
public void prePersist() {
    this.crtDt = new Date();
    this.updDt = this.crtDt;
 
    // created/updated by 업데이트
    Member user = (Member) SessionUtil.getSession().getAttribute("memberinfo");
    if (user != null) {
        this.crtBy = user.getMemSeq();
        this.updBy = this.crtBy;
    } else {
        this.crtBy = 0;
        this.updBy = 0;
    }
 
}
 
@PreUpdate
public void preUpdate() {
    this.updDt = new Date();
        
    // updated by 업데이트
    Member user = (Member) SessionUtil.getSession().getAttribute("memberinfo");
    if (user != null) {
        this.updBy = user.getMemSeq();
    } else {
        this.updBy = 0;
    }
       
}
cs

7, 23번 라인에서 1번 코드에서 작성한 "memberinfo"를 이용해서 정보 로그인 계정 정보를 얻기

 

 

해당 방법을 이용하면 원하는 어떤 곳에서도 세션 정보를 얻을 수 있다.

 

 

 

 

728x90
반응형

+ Recent posts