1
votes

Im trying to hook up Hibernate with my Spring application context. I am successfulyl wiring up a SessionFactory, but when I try to call getCurrentSession I see the following error:

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean$TransactionAwareInvocationHandler.invoke(AbstractSessionFactoryBean.java:270)
at $Proxy8.getCurrentSession(Unknown Source)
at org.company.web.ws.sample.impl.CheckSecurityImpl.verify(CheckSecurityImpl.java:31)
at org.company.web.ws.sample.impl.CheckSecurityImplTest.testCheckSecurity(CheckSecurityImplTest.java:28)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

I am configuring a datasource session factory and transaction manager. I have also specified that the transaction handling will be annotation driven

Here is my context xml:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/jdbc
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    ">


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
    <property name="url" value="jdbc:hsqldb:mem:murex" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean> 

<jdbc:initialize-database data-source="dataSource">
  <jdbc:script location="classpath:/db-schema.sql"/>
  <jdbc:script location="classpath:/db-testdata.sql"/>
</jdbc:initialize-database>

<!-- Hibernate Session Factory  -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="mappingResources">
       <list>
          <value>/security.hbm.xml</value>
       </list>
    </property> 
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>  

<tx:annotation-driven/>

<bean id="checkSecurityService" class="org.example.web.ws.sample.impl.CheckSecurityImpl" />

Here is the class where I am seeign the error:

@WebService(endpointInterface = "org.example.web.ws.sample.CheckSecurity")
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class CheckSecurityImpl implements CheckSecurity {

    @Autowired 
    private SessionFactory sessionFactory;

    @Transactional
    public CheckSecurityResponse verify(String propertyValue, String propertyType) {
        Session session = sessionFactory.getCurrentSession();
    }
}

When this is called sessionFactory is not null, but errors with the above error. If I use openSession everything works fine, but I understand this does not work with transactions.

Any ideas? Thanks

3
What is processing your autowiring? I don't see a component-scan or annotation-config in your context.xml. Is this in a different context? - MarkOfHall
@SteveHall Looks like that was the problem, this wa a context file for a test and didnt include the component scan. Good spot, if you post as an answer I will accept so others can make sure they dont miss this! - cowls

3 Answers

2
votes

The component-scan is missing from the context, so the @Transactional post processor isn't run to decorate the transaction wrapped methods.

-1
votes

Can you please post the full stack trace?

I am guessing the exception is being thrown by TransactionManager and not by getCurrentSession() in verify().

You are using TransactionManager and Session separately.

You could quickly test this by removing annotations for transactions.

For proper fix try using HibernateTemplate instead of using SessionFactory directly.

-1
votes

use following jars

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate.common</groupId>
        <artifactId>hibernate-commons-annotations</artifactId>
            <version>4.0.1.Final</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>4.0.1.Final</version>
    </dependency>

    <dependency>
        <groupId>antlr</groupId>
        <artifactId>antlr</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-runtime</artifactId>
<version>3.0</version>