Spring Framework
  1. Spring Framework
  2. SPR-8908

org.springframework.orm.hibernate4.HibernateTransactionManager fails with NoSuchMethodError against SessionFactory.getCurrentSession()

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Complete
    • Affects Version/s: 3.1 RC2
    • Fix Version/s: 3.1 GA
    • Component/s: None
    • Labels:
      None

      Description

      During transaction management following exception is thrown:

      java.lang.NoSuchMethodError: org.hibernate.SessionFactory.getCurrentSession()Lorg/hibernate/classic/Session;
      at org.springframework.orm.hibernate4.HibernateTransactionManager.doGetTransaction(HibernateTransactionManager.java:284)
      at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:335)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
      at com.iteezy.server.service.impl.UserServiceImpl$$EnhancerByCGLIB$$fe213902.getCurrentUser(<generated>)
      at com.iteezy.server.web.servlet.ErrorServlet.doGet(ErrorServlet.java:40)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:59)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
      at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:473)
      at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
      at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
      at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:455)
      at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:399)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:191)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
      at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
      at java.lang.Thread.run(Unknown Source)

        Issue Links

          Activity

          Hide
          Chris Beams added a comment -

          Juergen,

          This looks closely related to SPR-8776, however this is dealing with getCurrentSession() as opposed to openSession(). Perhaps a similar fix is in order.

          Show
          Chris Beams added a comment - Juergen, This looks closely related to SPR-8776 , however this is dealing with getCurrentSession() as opposed to openSession() . Perhaps a similar fix is in order.
          Hide
          Juergen Hoeller added a comment -

          Indeed. One only runs into this getCurrentSession() call in case of HibernateTransactionManager's "hibernateManagedSession" flag switched to "true", so I'm not surprised that it slipped through. In any case, fixed for GA.

          Juergen

          Show
          Juergen Hoeller added a comment - Indeed. One only runs into this getCurrentSession() call in case of HibernateTransactionManager's "hibernateManagedSession" flag switched to "true", so I'm not surprised that it slipped through. In any case, fixed for GA. Juergen
          Hide
          Daniel Fernández added a comment -

          Sorry for reopening this, but I'm still getting this error with 3.1.0.RELEASE and Hibernate 4.0.0.Final in a very strange scenario. I'll try to explain step-by-step:

          • I have a webapp (W) and a library (L). L is a dependency to W.
          • Both L and W are built using maven 3.
          • L has in its pom.xml dependencies on spring-core and spring-orm, both 3.1.0.RELEASE. It also has a dependency on hibernate-core-3.6.0.Final.
          • W has in its pom.xml dependencies on L, spring-core, -orm, -context, -context-support, -beans, -tx, -jdbc, and -web, all in 3.1.0.RELEASE. It also has dependencies on hibernate-core and hibernate-ehcache, both in 4.0.0.Final. There are many other library dependencies too, not related to spring nor hibernate.
          • After executing "mvn clean compile package" on W, the .war created does NOT contain the hibernate-3.6.0.Final.jar file (which is correct) nor any of its dependencies, and it adequately contains hibernate-4.0.0.Final.jar. It also contains L's .jar. Everything seems fine at the "/WEB-INF/lib" folder.
          • W has an OpenSessionInViewFilter set to org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
          • W declares an org.springframework.orm.hibernate4.LocalSessionFactoryBean, an org.springframework.orm.hibernate4.HibernateExceptionTranslator and a org.springframework.orm.hibernate4.HibernateTransactionManager. It also declares an org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
          • L has one class which @Autowires an org.hibernate.SessionFactory object and executes "this.sessionFactory.getCurrentSession()" on it. Let's call this class C1.
          • W has several classes which @Autowire an org.hibernate.SessionFactory object and execute "this.sessionFactory.getCurrentSession()" on it. Let's call these classes C2 and C3.
          • With this setup, C2 and C3 work perfectly fine, but C1 raises "NoSuchMethodException" on "this.sessionFactory.getCurrentSession()".
          • Nevertheless, if we go to L's pom.xml and substitute this library's dependency on hibernate-core-3.6.0.Final by a dependency on hibernate-core-4.0.0.Final, C1 starts to work OK, like C2 and C3 do.

          From the user's side, this error simply has no sense, because the hibernate-core-3.6.0.Final does never make it to the .war file, so there should be no reason to mistake Spring...

          I'm reopening this because Hibernate 3.6 and 4's APIs are quite similar, and AFAIK there shouldn't be a reason why a library with a 3.6 dependency on its POM not using any 3.6-specific features shouldn't work with a 4.0 on its classpath...

          Show
          Daniel Fernández added a comment - Sorry for reopening this, but I'm still getting this error with 3.1.0.RELEASE and Hibernate 4.0.0.Final in a very strange scenario. I'll try to explain step-by-step: I have a webapp (W) and a library (L). L is a dependency to W. Both L and W are built using maven 3. L has in its pom.xml dependencies on spring-core and spring-orm, both 3.1.0.RELEASE. It also has a dependency on hibernate-core-3.6.0.Final. W has in its pom.xml dependencies on L, spring-core, -orm, -context, -context-support, -beans, -tx, -jdbc, and -web, all in 3.1.0.RELEASE. It also has dependencies on hibernate-core and hibernate-ehcache, both in 4.0.0.Final. There are many other library dependencies too, not related to spring nor hibernate. After executing "mvn clean compile package" on W, the .war created does NOT contain the hibernate-3.6.0.Final.jar file (which is correct) nor any of its dependencies, and it adequately contains hibernate-4.0.0.Final.jar. It also contains L's .jar. Everything seems fine at the "/WEB-INF/lib" folder. W has an OpenSessionInViewFilter set to org.springframework.orm.hibernate4.support.OpenSessionInViewFilter W declares an org.springframework.orm.hibernate4.LocalSessionFactoryBean, an org.springframework.orm.hibernate4.HibernateExceptionTranslator and a org.springframework.orm.hibernate4.HibernateTransactionManager. It also declares an org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor L has one class which @Autowires an org.hibernate.SessionFactory object and executes "this.sessionFactory.getCurrentSession()" on it. Let's call this class C1. W has several classes which @Autowire an org.hibernate.SessionFactory object and execute "this.sessionFactory.getCurrentSession()" on it. Let's call these classes C2 and C3. With this setup, C2 and C3 work perfectly fine, but C1 raises "NoSuchMethodException" on "this.sessionFactory.getCurrentSession()". Nevertheless, if we go to L's pom.xml and substitute this library's dependency on hibernate-core-3.6.0.Final by a dependency on hibernate-core-4.0.0.Final, C1 starts to work OK, like C2 and C3 do. From the user's side, this error simply has no sense, because the hibernate-core-3.6.0.Final does never make it to the .war file, so there should be no reason to mistake Spring... I'm reopening this because Hibernate 3.6 and 4's APIs are quite similar, and AFAIK there shouldn't be a reason why a library with a 3.6 dependency on its POM not using any 3.6-specific features shouldn't work with a 4.0 on its classpath...
          Hide
          Juergen Hoeller added a comment -

          I'm afraid there is a key difference between the Hibernate 3.6 and 4.0 APIs: SessionFactory.getCurrentSession() used to declare org.hibernate.classic.Session as its return type in 3.6 but returns org.hibernate.Session in 4.0. Unfortunately, this is not very obvious.

          Any code compiled against Hibernate 3.6, or against a classpath where the Hibernate 3.6 jar sits before the Hibernate 4.0 jar, will be compiled against the old version of that method and will raise a NoSuchMethodError when running against Hibernate 4.0.

          Since this is about calls in your own repository classes, there is nothing we can do about this. You need to make sure that all your repository implementation classes are being compiled against the same Hibernate API generation that they run against.

          Juergen

          Show
          Juergen Hoeller added a comment - I'm afraid there is a key difference between the Hibernate 3.6 and 4.0 APIs: SessionFactory.getCurrentSession() used to declare org.hibernate.classic.Session as its return type in 3.6 but returns org.hibernate.Session in 4.0. Unfortunately, this is not very obvious. Any code compiled against Hibernate 3.6, or against a classpath where the Hibernate 3.6 jar sits before the Hibernate 4.0 jar, will be compiled against the old version of that method and will raise a NoSuchMethodError when running against Hibernate 4.0. Since this is about calls in your own repository classes, there is nothing we can do about this. You need to make sure that all your repository implementation classes are being compiled against the same Hibernate API generation that they run against. Juergen
          Hide
          Daniel Fernández added a comment -

          You are absolutely right, Juergen. Because org.hibernate.classic.Session extended org.hibernate.Session we never really noticed that specific matter because we always assigned the result to org.hibernate.Session. And now Hibernate 4 has removed classic.Session and provoked this.

          This is a huge issue for hibernate-depending libraries, as no existing version of any of them will be able to work both with both Hibernate 3.x and 4.x if they call "getCurrentSession()", even if they only make use of parts of hibernate that haven't changed. I'm honestly shocked.

          But as you say, there's nothing you can do from Spring for solving it. Thanks a lot and sorry for reopening this for no real reason.

          Show
          Daniel Fernández added a comment - You are absolutely right, Juergen. Because org.hibernate.classic.Session extended org.hibernate.Session we never really noticed that specific matter because we always assigned the result to org.hibernate.Session. And now Hibernate 4 has removed classic.Session and provoked this. This is a huge issue for hibernate-depending libraries, as no existing version of any of them will be able to work both with both Hibernate 3.x and 4.x if they call "getCurrentSession()", even if they only make use of parts of hibernate that haven't changed. I'm honestly shocked. But as you say, there's nothing you can do from Spring for solving it. Thanks a lot and sorry for reopening this for no real reason.
          Hide
          Juergen Hoeller added a comment -

          Indeed, this is a quite big deal for any dependent library. It's the same with SessionFactory.openSession(): Anyone calling that method will have to deal with the difference in return value between Hibernate 3 and Hibernate 4 as well. The only solution is to use reflection, which is exactly what we do in Spring's Hibernate support now.

          In my opinion, it was a mistake to ever declare org.hibernate.classic.Session there back in the Hibernate 3.0.1 days... They should rather have expected classic Hibernate users to cast the return value to org.hibernate.classic.Session instead, and designed getCurrentSession() itself to declare org.hibernate.Session right from the start.

          Juergen

          Show
          Juergen Hoeller added a comment - Indeed, this is a quite big deal for any dependent library. It's the same with SessionFactory.openSession(): Anyone calling that method will have to deal with the difference in return value between Hibernate 3 and Hibernate 4 as well. The only solution is to use reflection, which is exactly what we do in Spring's Hibernate support now. In my opinion, it was a mistake to ever declare org.hibernate.classic.Session there back in the Hibernate 3.0.1 days... They should rather have expected classic Hibernate users to cast the return value to org.hibernate.classic.Session instead, and designed getCurrentSession() itself to declare org.hibernate.Session right from the start. Juergen
          Hide
          Jonathan Lee added a comment -

          Is this really fixed? I think I'm still getting this in my spring 3.1/hibernate 4.0 setup... Due to the nature of this problem I have posted my configs on StackOverflow to ensure that the problem doesn't lie with my setup.

          http://stackoverflow.com/questions/8846586/no-session-found-for-current-thread-spring-3-1-x-and-hibernate-4

          The crux of it is I am still getting the following exception:
          SEVERE: Servlet.service() for servlet [lystra] in context with path [/lystra] threw exception [Request processing failed; nested exception is org.hibernate.HibernateException: No Session found for current thread] with root cause org.hibernate.HibernateException: No Session found for current thread at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:881)

          Show
          Jonathan Lee added a comment - Is this really fixed? I think I'm still getting this in my spring 3.1/hibernate 4.0 setup... Due to the nature of this problem I have posted my configs on StackOverflow to ensure that the problem doesn't lie with my setup. http://stackoverflow.com/questions/8846586/no-session-found-for-current-thread-spring-3-1-x-and-hibernate-4 The crux of it is I am still getting the following exception: SEVERE: Servlet.service() for servlet [lystra] in context with path [/lystra] threw exception [Request processing failed; nested exception is org.hibernate.HibernateException: No Session found for current thread] with root cause org.hibernate.HibernateException: No Session found for current thread at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:881)
          Hide
          Juergen Hoeller added a comment -

          Your exception is different, actually: This original issue was about a NoSuchMethodError whereas you are running into a scenario where the call does work but no associated Session is being found at runtime.

          I suspect your problem is related to SPR-9020: In our Hibernate 4 support, we only find a current Session within an actual transaction (at this point). This means it will work within Propagation.REQUIRED but not within SUPPORTS, despite the latter having worked with Hibernate 3. See SPR-9020 for the ongoing discussion.

          Juergen

          Show
          Juergen Hoeller added a comment - Your exception is different, actually: This original issue was about a NoSuchMethodError whereas you are running into a scenario where the call does work but no associated Session is being found at runtime. I suspect your problem is related to SPR-9020 : In our Hibernate 4 support, we only find a current Session within an actual transaction (at this point). This means it will work within Propagation.REQUIRED but not within SUPPORTS, despite the latter having worked with Hibernate 3. See SPR-9020 for the ongoing discussion. Juergen

            People

            • Assignee:
              Juergen Hoeller
              Reporter:
              Mat Banik
              Last updater:
              Trevor Marshall
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                2 years, 14 weeks, 5 days ago