【问题标题】:HTTP Status 500 - Request processing failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to threadHTTP 状态 500 - 请求处理失败;嵌套异常是 org.hibernate.HibernateException: No Hibernate Session bound to thread
【发布时间】:2013-12-16 10:27:14
【问题描述】:

我编写测试弹簧应用程序。我有问题。

我的 java 代码:

控制器方法

    @RequestMapping(value = "/index")
    public String setupForm()
    {    
        mainService.getAllRecords());
    }

服务接口

@Transactional
public interface MainService
{

    public List<Record> getAllRecords();
}

服务实现

@Service("mainService")
@Transactional
public class MainServiceImpl implements MainService
{
    @Autowired
    private MainDao mainDao;


    @Transactional
    public List<Record> getAllRecords()
    {

        return mainDao.getAllRecords();
    }

}

dao 不标记为@Transactional。

我看到下一个错误:

HTTP Status 500 - Request processing failed; nested exception is org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

如果我将 dao 接口标记为 @Transactional - 效果很好。

配置:

web.xml

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param> 

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

数据.xml

<!-- Настраивает управление транзакциями с помощью аннотации @Transactional -->
    <tx:annotation-driven transaction-manager="transactionManager" />
    <!-- Менеджер транзакций -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:messages" />
        <property name="defaultEncoding" value="UTF-8" />
    </bean>
    <!-- Настройки бина dataSource будем хранить в отдельном файле -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" p:location="/WEB-INF/jdbc.properties" />
    <!-- Непосредственно бин dataSource -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="${jdbc.driverClassName}"
        p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" p:password="${jdbc.password}" />
    <!-- Настройки фабрики сессий Хибернейта -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.connection.charSet">UTF-8</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
            </props>
        </property>
    </bean>

根上下文.xml

<context:component-scan base-package="com.wp.crud.dao"/>
<context:component-scan base-package="com.wp.crud.controller"/>

<!--
 Файл с настройками ресурсов для работы с данными (Data Access Resources) 
-->
 <import resource="data.xml"/>   

servlet-context.xml

<annotation-driven />

    <!-- Всю статику (изображения, css-файлы, javascript) положим в папку webapp/resources и замаппим их на урл вида /resources/** -->

    <resources mapping="/resources/**" location="/resources/" />
    <!-- Отображение видов на jsp-файлы, лежащие в папке /WEB-INF/views -->

    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>
    <!-- Файл с настройками контроллеров -->

    <beans:import resource="controllers.xml" />

controllers.xml

<context:component-scan base-package="com.wp.crud.controller"/>

我不明白这个问题的原因。

你能帮帮我吗?

【问题讨论】:

    标签: java spring hibernate session transactions


    【解决方案1】:

    在您的 web.xml 中,您缺少声明 Hibernate OpenSessionInViewFilter,它提供您的休眠会话以在您的请求过程中打开:

    <filter>
            <filter-name>hibernateFilter</filter-name>
            <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
            <init-param>
                <param-name>singleSession</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>hibernateFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    

    这应该可以解决您的错误。 请注意,过滤器类是针对 Hibernate4 的,您需要在 Hibernate3 的情况下进行修复

    【讨论】:

    • 这是工作建议。但是我无法理解将这个 sn-p 添加到 web.xml 后问题解决了什么
    • OpenSessionInViewFilter 是一个 Web 过滤器,可在您发出请求并将其绑定到 threadlocal 时打开休眠会话。因此,在您的 dao 中,您始终可以调用 sessionFactory.getCurrentSession()
    • 似乎,我看到了带有 @Transactional 而没有这个过滤器的例子。是真的吗?
    • 我找到了我的旧项目,还有我使用hibernate+spring+transactional
    • 我一直使用这个过滤器和休眠..所以我不知道没有它它是如何工作的..对不起..
    【解决方案2】:
    <context:component-scan base-package="com.wp.crud.controller"/>
    

    root-context.xmlcontrollers.xml 中你真的需要这条线吗?

    我认为首先你应该用你的服务包替换(如果尚未替换)com.wp.crud.controller in root-context.xml

    您还应该将这些组件扫描放置在data.xml 的这一行之后的某个位置:

    <tx:annotation-driven transaction-manager="transactionManager" />
    

    所以@Transactional 注释可能会对扫描的类产生影响。

    顺便说一句,服务接口上不需要@Transactional

    【讨论】:

    • 通常我会从根上下文中排除控制器,将它们放入 servlet 上下文中。
    • @EmanueleRighetto 没关系,但现在有两个 component-scans 用于控制器包,我看不到任何服务
    • 是的,你说得对,我没有注意到一个组件扫描只是拾取 dao
    • 对不起,最大。我知道这很糟糕但是我的控制器和服务位于同一个包中。
    • @gstackoverflow 所以您只在 web.xml 中进行了更改,现在可以了吗?
    【解决方案3】:
    <tx:annotation-driven transaction-manager="txManager"/>
        <!-- Transaction Manager is defined -->
        <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    

    将此 jar 文件添加到库中
    aopalliance-1.0.jar

    【讨论】:

      猜你喜欢
      • 2013-04-05
      • 2014-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多