Announcement Announcement Module
Collapse
No announcement yet.
Hibernate TX Support Broken in 2.5-rc1 Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate TX Support Broken in 2.5-rc1

    I think the transaction support for hibernate may be broken in 2.5. Code that did work under 2.0 now fails with this trace:

    Code:
    org.hibernate.HibernateException: persist is not valid without active transaction
    	at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:297)
    	at $Proxy34.persist(Unknown Source)
    	at foo.bar.FooService.addFoo(FooService.java:36)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:301)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    	at $Proxy32.addFoo(Unknown Source)
    	at foo.bar.FooTest.testAddFoo(FooTest.java:21)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at junit.framework.TestCase.runTest(TestCase.java:154)
    	at junit.framework.TestCase.runBare(TestCase.java:127)
    	at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:76)
    	at junit.framework.TestResult$1.protect(TestResult.java:106)
    	at junit.framework.TestResult.runProtected(TestResult.java:124)
    	at junit.framework.TestResult.run(TestResult.java:109)
    	at junit.framework.TestCase.run(TestCase.java:118)
    	at junit.framework.TestSuite.runTest(TestSuite.java:208)
    	at junit.framework.TestSuite.run(TestSuite.java:203)
    	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
    I've tried both the transactional annotation support and the schema based approaches. My context is currently as follows:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xsi:schemaLocation="
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    	">
    
    	<aop:config>
    		<aop:pointcut id="defaultServiceOperation"
    			expression="execution(* foo.bar.FooService.*(..))" />
    		<aop:advisor pointcut-ref="defaultServiceOperation"
    			advice-ref="defaultTxAdvice" />
    	</aop:config>
    
    	<tx:advice id="defaultTxAdvice">
    		<tx:attributes>
    			<tx:method name="get*" read-only="true" />
    			<tx:method name="add*" />
    		</tx:attributes>
    	</tx:advice>
    
    	<bean id="fooService"
    		class="foo.bar.FooService">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    
    	<bean id="transactionManager"
    		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    
    	<bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    		<property name="configurationClass"
    			value="org.hibernate.cfg.AnnotationConfiguration" />
    		<property name="annotatedClasses">
    			<list>
    				...
    			</list>
    		</property>
    		<property name="dataSource" ref="dataSource" />
    		<property name="hibernateProperties">
    			<props>
    				...
    			</props>
    		</property>
    	</bean>
    
    	<bean id="dataSource"
    		class="org.apache.commons.dbcp.BasicDataSource"
    		destroy-method="close">
    		...
    	</bean>
    
    </beans>
    I have determined it has something to do with sessionFactory.getCurrentSession() since using sessionFactory.openSession() seems to work. I'm willing to bet there's a decent amount of existing code using the former approach. The fact that it suddenly stopped working is probably a bug.

    Anyone run into this yet? Resolved it? Should I submit a bug?
    Last edited by redijedi; Oct 26th, 2007, 09:52 AM.

  • #2
    Can you show us a full list of hibernateProperties you set?

    Comment


    • #3
      They're currently held in a props file and used via a PropertyPlaceholderConfigurer in a separate context file that just holds the placeholder bean at this point.

      Code:
      dao.hibernate.dialect=org.hibernate.dialect.MySQLDialect
      dao.hibernate.connection.pool_size=10
      dao.hibernate.current_session_context_class=thread
      dao.hibernate.cache.use_query_cache=true
      dao.hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
      dao.hibernate.show_sql=true
      dao.hibernate.hbm2dll.auto=create-drop
      I omitted them since I thought there's not much interesting here.

      Comment


      • #4
        Try to take this out:

        dao.hibernate.current_session_context_class=thread

        Comment


        • #5
          No dice. Different error though.

          Code:
          org.hibernate.HibernateException: No CurrentSessionContext configured!
          	at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:542)
          	at foo.bar.FooService.addFoo(FooService.java:37)
          	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          	at java.lang.reflect.Method.invoke(Method.java:597)
          	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:301)
          	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
          	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
          	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
          	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
          	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
          	at $Proxy32.addFoo(Unknown Source)
          	at foo.bar.FooTest.testAddFoo(FooTest.java:18)
          	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          	at java.lang.reflect.Method.invoke(Method.java:597)
          	at junit.framework.TestCase.runTest(TestCase.java:154)
          	at junit.framework.TestCase.runBare(TestCase.java:127)
          	at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:76)
          	at junit.framework.TestResult$1.protect(TestResult.java:106)
          	at junit.framework.TestResult.runProtected(TestResult.java:124)
          	at junit.framework.TestResult.run(TestResult.java:109)
          	at junit.framework.TestCase.run(TestCase.java:118)
          	at junit.framework.TestSuite.runTest(TestSuite.java:208)
          	at junit.framework.TestSuite.run(TestSuite.java:203)
          	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
          	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
          	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
          	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
          	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
          	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

          Comment


          • #6
            That's very strange. In LSFB:
            Code:
              if (isExposeTransactionAwareSessionFactory()) {
                // Set Hibernate 3.1 CurrentSessionContext implementation,
                // providing the Spring-managed Session as current Session.
                // Can be overridden by a custom value for the corresponding Hibernate property.
            	config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());
            }
            currentSessionContext is set and if you are not manipulating it somewhere it should stay that way.

            Comment

            Working...
            X