0

My project has Open session in view enabled and we cannot disable it at this point. We are using spring boot.

I have a method that does db read calls and rest calls. I do NOT need transactional boundary over this method. How do I disable the transaction in this method. I have tried using

@Transaction(propagation=Propagation.NEVER 
and 
@Transaction(propagation=Propagation.NOT_SUPPORTED)

But the transaction still seems to exist. I know this because there are some lazily loaded relationships that gets loaded if I access them with in this method.

public void doSomething() {
    makeDbCall();
    makeRestCall();
    makeDbCallAgain();
}
Nero
  • 422
  • 8
  • 22
  • Lazy loading means your entities are not detached - this doesn't necessarily mean you have an open transaction, as it'll depend on what they are attached to and what is holding that context/persistence unit. How have you configured your session here? – Chris Sep 30 '22 at 20:44

1 Answers1

1

The easiest and safest way that I can think of is to customize the OpenEntityManagerInViewInterceptor to just exclude the request that you do not want to apply OSIV on it. Something like :

public class MyOpenEntityManagerInViewInterceptor extends OpenEntityManagerInViewInterceptor {
    

  
    private boolean isExcludeOsiv(WebRequest request){
        //refer to https://stackoverflow.com/questions/51921635/how-to-get-requests-uri-from-webrequest-in-spring for getting the URL path from the WebRequest for checking
    }

 
    @Override 
    public void preHandle(WebRequest request) throws DataAccessException {
        if(isExcludeOsiv(request)){
            return ;
        }
        super.preHandle(requset);
    }

    @Override
    public void afterCompletion(WebRequest request, @Nullable Exception ex) throws DataAccessException {
        if(isExcludeOsiv(request)){
            return ;
        }
        super.afterCompletion(requset,ex);
   }

} 

And use the following configuration to disable the default OSIV setting provided by spring-boot but use this customised OpenEntityManagerInViewInterceptor instead :

@Configuration
public class WebConfig implements WebMvcConfigurer {


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
            registry.addWebRequestInterceptor(new MyOpenEntityManagerInViewInterceptor());
    }
}
Ken Chan
  • 84,777
  • 26
  • 143
  • 172