Spring & amp; Hibernate: non-transactional service methods

advertisements

I want my read methods not to use a transaction since this is just not needed at all, I only mark my create/update methods with @Transactional. But how do I do this? I have a pretty basic configuration of Spring with etc...

SessionFactory is injected in my DAO, and in each method I call sessionFactory.getCurrentSession().doQueryStuff();

This, however results in this error:

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

If you need my Spring configuration:

<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/oxm
    http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util-3.0.xsd">

<context:annotation-config />
<context:component-scan base-package="be.howest.kidscalcula" />
<mvc:annotation-driven />

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/views/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

<bean id="myDataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost/kidscalcula" />
    <property name="username" value="root" />
    <property name="password" value="" />
</bean>

<bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
    id="sessionFactory">
    <property name="dataSource" ref="myDataSource" />
    <property name="mappingResources">
        <list>
            <value>be/howest/kidscalcula/model/Foto.hbm.xml</value>
            <value>be/howest/kidscalcula/model/Kindleerplanonderdeel.hbm.xml
            </value>
            <value>be/howest/kidscalcula/model/Klas.hbm.xml</value>
            <value>be/howest/kidscalcula/model/Leerkracht.hbm.xml</value>
            <value>be/howest/kidscalcula/model/Leerling.hbm.xml</value>
            <value>be/howest/kidscalcula/model/Leerplan.hbm.xml</value>
            <value>be/howest/kidscalcula/model/LeerplanOefenreeks.hbm.xml
            </value>
            <value>be/howest/kidscalcula/model/Leerplanonderdeel.hbm.xml</value>
            <value>be/howest/kidscalcula/model/Niveau.hbm.xml</value>
            <value>be/howest/kidscalcula/model/Oefenreeks.hbm.xml</value>
            <value>be/howest/kidscalcula/model/Overgangsregel.hbm.xml</value>
            <value>be/howest/kidscalcula/model/Rapport.hbm.xml</value>
            <value>be/howest/kidscalcula/model/RapportLeerplanonderdeel.hbm.xml
            </value>
            <value>be/howest/kidscalcula/model/Schooljaar.hbm.xml</value>
            <value>be/howest/kidscalcula/model/Subonderdeel.hbm.xml</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.connection.pool_size">3</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.use_sql_comments">true</prop>
            <prop key="hibernate.cache.use_second_level_cache">false</prop>

        </props>
    </property>
</bean>

<!-- Configure the multipart resolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- one of the properties available; the maximum file size in bytes -->
    <property name="maxUploadSize" value="500000" />
</bean>

<!--
    Transaction manager for a single Hibernate SessionFactory (alternative
    to JTA)
-->
<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
        <ref bean="sessionFactory" />
    </property>
</bean>

<tx:annotation-driven />

Does this error have anything to do with the fact that Propagation is standard Required?


It is possible to start a session outside of a transaction even when using Spring transaction management. Call sessionFactory.openSession() to get hold of a new session. This session is local in that it is not bound to a thread and so won't be returned when you call sessionFactory.getCurrentSession(). You'll have to manage it and make sure it's properly closed at the the end of your session or if an error occurs.