Search code examples
grailsgrails-ormupgrade

Upgrade from grails 2.5.4 to 3.1.8, GORM error


I am trying to upgrade project from grails 2.5.4 to 3.1.8 and now I am stuck on the following error.

org.springframework.dao.DataAccessResourceFailureException: Could not obtain current Hibernate Session; nested exception is org.hibernate.HibernateException: No Session found for current thread
org.grails.orm.hibernate.GrailsHibernateTemplate.getSession(GrailsHibernateTemplate.java:227)
org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:183)
org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:140)
org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:110)
org.grails.orm.hibernate.AbstractHibernateGormStaticApi.findWhere(AbstractHibernateGormStaticApi.groovy:335)
org.grails.datastore.gorm.GormStaticApi.findWhere(GormStaticApi.groovy:658)
org.grails.datastore.gorm.GormEntity$Trait$Helper.findWhere(GormEntity.groovy:841)
org.grails.datastore.gorm.GormEntity$Trait$Helper$findWhere$4.call(Unknown Source)
com.etherapia.portal.security.User.findWhere(User.groovy)
com.etherapia.portal.security.User$findWhere$0.call(Unknown Source)
grails.plugin.springsecurity.userdetails.GormUserDetailsService.$tt__loadUserByUsername(GormUserDetailsService.groovy:60)
grails.plugin.springsecurity.userdetails.GormUserDetailsService$_loadUserByUsername_closure1.doCall(GormUserDetailsService.groovy)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1426)
org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1021)
groovy.lang.Closure.call(Closure.java:426)
groovy.lang.Closure.call(Closure.java:442)
grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
grails.plugin.springsecurity.userdetails.GormUserDetailsService.loadUserByUsername(GormUserDetailsService.groovy)
grails.plugin.springsecurity.userdetails.GormUserDetailsService.loadUserByUsername(GormUserDetailsService.groovy:71)
org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.processAutoLoginCookie(TokenBasedRememberMeServices.java:123)
org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.autoLogin(AbstractRememberMeServices.java:113)
org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:97)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:62)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:75)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

root cause

org.hibernate.HibernateException: No Session found for current thread
org.grails.orm.hibernate.GrailsSessionContext.currentSession(GrailsSessionContext.java:117)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
org.grails.orm.hibernate.SessionFactoryProxy.getCurrentSession(SessionFactoryProxy.java:148)
org.grails.orm.hibernate.GrailsHibernateTemplate.getSession(GrailsHibernateTemplate.java:225)
org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:183)
org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:140)
org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:110)
org.grails.orm.hibernate.AbstractHibernateGormStaticApi.findWhere(AbstractHibernateGormStaticApi.groovy:335)
org.grails.datastore.gorm.GormStaticApi.findWhere(GormStaticApi.groovy:658)
org.grails.datastore.gorm.GormEntity$Trait$Helper.findWhere(GormEntity.groovy:841)
org.grails.datastore.gorm.GormEntity$Trait$Helper$findWhere$4.call(Unknown Source)
com.etherapia.portal.security.User.findWhere(User.groovy)
com.etherapia.portal.security.User$findWhere$0.call(Unknown Source)
grails.plugin.springsecurity.userdetails.GormUserDetailsService.$tt__loadUserByUsername(GormUserDetailsService.groovy:60)
grails.plugin.springsecurity.userdetails.GormUserDetailsService$_loadUserByUsername_closure1.doCall(GormUserDetailsService.groovy)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

The error shows up only in mozzila firefox, while chroome loads the page without assests. Images,css,js are not loaded properly in chroome.

Do you know where could be an issue?


Solution

  • In version 3.1.1 of the spring security core plugin the method generating the exception is annotated as @Transactional (see below). Maybe you are using an older version?

    class GormUserDetailsService implements GrailsUserDetailsService {
    
        protected Logger log = LoggerFactory.getLogger(getClass())
    
        /**
         * Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least one role, so
         * we give a user with no granted roles this one which gets past that restriction but
         * doesn't grant anything.
         */
        static final GrantedAuthority NO_ROLE = new SimpleGrantedAuthority(SpringSecurityUtils.NO_ROLE)
    
        /** Dependency injection for the application. */
        GrailsApplication grailsApplication
    
        @Transactional(readOnly=true, noRollbackFor=[IllegalArgumentException, UsernameNotFoundException])
        UserDetails loadUserByUsername(String username, boolean loadRoles) throws UsernameNotFoundException {
    
            def conf = SpringSecurityUtils.securityConfig
            String userClassName = conf.userLookup.userDomainClassName
            def dc = grailsApplication.getDomainClass(userClassName)
            if (!dc) {
                throw new IllegalArgumentException("The specified user domain class '$userClassName' is not a domain class")
            }
    
            Class<?> User = dc.clazz
    
            def user = User.findWhere((conf.userLookup.usernamePropertyName): username)
            if (!user) {
                log.warn 'User not found: {}', username
                throw new NoStackUsernameNotFoundException()
            }
    
            Collection<GrantedAuthority> authorities = loadAuthorities(user, username, loadRoles)
            createUserDetails user, authorities
        }
    ...
    }