簡體   English   中英

Spring和Hibernate:非事務性服務方法

[英]Spring & Hibernate: non transactional service methods

我希望我的讀取方法不使用事務,因為根本不需要它,我只用@Transactional標記我的創建/更新方法。 但是我該怎么做? 我有一個非常基本的配置Spring等...

SessionFactory注入我的DAO,在每個方法中我調用sessionFactory。 。的getCurrentSession()doQueryStuff();

但是,這會導致此錯誤:

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

如果你需要我的Spring配置:

<?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 />

此錯誤是否與傳播是標准要求事實有關?

將方法標記為事務性並且只讀以確保事務不會修改任何數據:

@Transactional(readOnly=true)

在使用Hibernate時,這是一個非常有用的優化。 要閱讀有關此批注的含義的更多信息,這里有一篇很棒的文章: 使用Spring和Hibernate進行只讀事務

正如消息清楚地說明的那樣,沒有會話綁定到線程,並且您指定的配置不允許創建“非事務”會話。 我將嘗試解釋每個場景。

當你的配置中啟用了Spring的事務時(正如你所做的那樣),當調用SessionFactory.getCurrentSession時,Spring將使用代理來封裝SessionFactory對象,該代理會阻止創建新會話(如果尚未存在)。 代理只會獲取綁定到本地線程的當前會話,並且代碼不允許創建臨時會話(非事務性)。 這是您的配置阻止非交易會話創建的方式。

當您使用@Transactional注釋方法/類時,Spring的TransactionInterceptor將創建一個會話,並在調用該方法時將其綁定到當前線程,以便以后可用。 Spring的OpenSessionInViewFilter,如果啟用,還會將會話綁定到當前線程。 由於您沒有執行任何這些操作,因此未找到線程綁定會話。

你應該做的是使用@Transactional(readOnly = True)注釋你的類,然后使用@Transactional(readOnly = False)注釋你的創建/更新/刪除方法。 在讀取數據時,必須具有只讀事務。 這可以確保您無法在該呼叫期間提交數據。

即使使用Spring事務管理,也可以在事務之外啟動會話。 調用sessionFactory.openSession()來獲取新會話。 此會話是本地會話,因為它不綁定到線程,因此在調用sessionFactory.getCurrentSession()時不會返回。 您必須對其進行管理,並確保在會話結束時正確關閉或發生錯誤。

沒有(休眠)會話,您無法訪問數據。

提供此類會話的一種方法是(使用spring時):

  • org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
  • org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter (這取決於您使用持久性提供程序的方式)

這些fiters的積極副作用是,在呈現JSP視圖時會話仍處於打開狀態 - 因此在呈現時訪問此類尚未加載的屬性時,您將不會遇到延遲加載問題。

@see http://community.jboss.org/wiki/OpenSessioninView

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM