【问题标题】:Spring MVC - No Hibernate Session bound to threadSpring MVC - 没有绑定到线程的休眠会话
【发布时间】:2014-07-20 09:19:36
【问题描述】:

我在休眠中的会话有问题:

INFO: Starting ProtocolHandler ["http-bio-8080"]
2013-09-10 16:23:11 org.apache.catalina.startup.Catalina start
 INFO: Server startup in 4000 ms
2013-09-10 16:23:13 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/portal] threw          exception [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] with root cause
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.SpringSessionContext.currentSession(SpringSessionContext.java:63)
    at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
    at com.myportal.portal.model.HibernateDao.getSessionFactory(HibernateDao.java:31)
    at com.myportal.portal.model.HibernateDao.testowa(HibernateDao.java:46)
    at com.myportal.portal.controllers.HomeController.home(HomeController.java:35)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

我已经阅读了有关此问题的一些信息,但解决方案不适用于我的情况。

我的道课:

package com.myportal.portal.model;
import org.hibernate.classic.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.myportal.portal.entity.User;

@Repository
@Transactional(propagation=Propagation.REQUIRED)
public class HibernateDao {
    @Autowired
    private SessionFactory sessionFactory;


    public HibernateDao()
    {

    }
    public HibernateDao(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }
    private Session getSessionFactory()
    {
        return sessionFactory.getCurrentSession();
    }

    private void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    public void testowa()
    {
        User u = new User();
        //SessionFactory sf = getSessionFactory();
        //Session s = sf.openSession().beginTransaction()

        // problem with this
        Session session = getSessionFactory();
        //session.save(u);

    }
}

根上下文.xml

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

    <!-- Root Context: defines shared resources visible to all other web components -->


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

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost/hibernate1"/>
    <property name="username" value="root2"/>
    <property name="password" value=""/>
    <property name="initialSize" value="5"/>
    <property name="maxActive" value="10"/>
</bean>    

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
   <property name="dataSource" ref="dataSource"/>
   <property name="packagesToScan" value="com.spoleczniak.projekt.model"/>
   <property name="hibernateProperties">
       <props>
           <prop key="dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
           <prop key="show_sql">true</prop>
       </props>
   </property>
</bean>

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

     <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

</beans>

servlet-context.xml

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
    <context:annotation-config/>
<context:component-scan base-package="com.myportal.portal" />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <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>

我是这样使用的:

@Controller
public class RegisterController {

    @Autowired
    private HibernateDao hibernateDao;

    @RequestMapping(value="/register")
    public String registerForm()
    {
        hibernateDao.testowa();
        return "register";
    }
}

我该如何解决?

我更改了DAO并创建了UserService,但仍然出现错误:

道:

@Repository
public class HibernateDao {
    @Autowired
    private SessionFactory sessionFactory;


    public HibernateDao()
    {

    }
    public HibernateDao(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }
    private Session getSessionFactory()
    {
        return sessionFactory.getCurrentSession();
    }

    private void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    public void testowa()
    {
        User u = new User();
        //SessionFactory sf = getSessionFactory();
        //Session s = sf.openSession().beginTransaction()

        // problem with this
        Session session = getSessionFactory();
        //session.save(u);

    }
} 

用户服务:

@Service
public class UserService {

    @Autowired
    private HibernateDao hibernateDao;


    @Transactional
    public void addContact() 
    {
        hibernateDao.testowa(); 
    }
}

控制器:

@Controller
public class RegisterController {

    @Autowired
    private UserService userService;

    @RequestMapping(value="/register")
    public String registerForm()
    {
        userService.addContact();
        return "register";
    }
}

【问题讨论】:

  • 看起来您为 servlet-context.xml 发布的内容与为 root-context.xml 发布的内容相同。那是个错误,对吗?
  • 对不起,我在这个帖子中犯了错误。我更正了帖子。

标签: java spring hibernate spring-mvc


【解决方案1】:

发生的事情是您的servlet-context.xml 正在覆盖您的root-context.xml 中的bean,因为它为包含@Repository 类的包声明了component-scan。在servlet-context.xml,你有

<context:component-scan base-package="com.myportal.portal" />

当您的 HibernateDao 课程在 com.myportal.portal.model 中时。这个ApplicationContext 将创建一个HibernateDao bean没有事务管理,因为它没有&lt;tx:annotation-driven&gt;。在@Controller 中自动装配的HibernateDao bean 是这个,而不是来自root-context.xml(具有事务管理)的那个。

要解决这个问题,您需要先添加

<context:component-scan base-package="com.myportal.portal.model" />

到您的root-context.xml 并删除&lt;context:annotation-config/&gt;(这是多余的)。然后,您想将servlet-context.xml 中的component-scan 修改为不包含@Repository 类包的更具体的内容

<context:component-scan base-package="com.myportal.portal.controllers" />

该包将包含您的@Controller 类。你也不需要&lt;context:annotation-config&gt;

【讨论】:

  • 好的,我改变了它。现在我在创建时遇到问题:在文件 [I:\Spring\vfabric-tc-server-developer-2.8.1 中定义名称为“hibernateDao”的 bean 创建时出错.RELEASE\base-instance\wtpwebapps\portalSpol\WEB-INF\classes\com\myportal\portal\model\HibernateDao.class]:bean 初始化失败;嵌套异常是 java.lang.NoClassDefFoundError: org/objectweb/asm/util/TraceClassVisitor
  • 我添加了 asm 和 cglib 依赖,这个错误消失了。现在我有:在名称为“appServlet”的 DispatcherServlet 中找不到带有 URI [/portal/] 的 HTTP 请求的映射。所以我认为 看不到我的控制器(控制器在这个包中)。在修改之前它工作正常。
  • 好的,现在可以正常使用了。感谢您的帮助,您的建议对我很有帮助。
【解决方案2】:
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

这意味着该线程中没有当前事务。

正如您纠正我的那样,该类使用 @Transactional 进行了注释,但我看到它没有实现接口。生成的代理可能不会像在控制器没有实现接口的情况下注释控制器那样公开注释。

See why CGLIB proxies do not retain certain annotations.

【讨论】:

  • 哦对了,没有完整阅读代码。但是我现在检查了 DAO 对象没有实现接口。可能生成的代理没有在运行时暴露注解。
  • 如果类路径中缺少 CGLIB,初始化步骤会报错。
  • 不是CGLIB不存在,而是CGLIB创建子类来做代理,如果没有用@Inherited注解子类不保留注解
  • 代理不需要注解,因为注解而构建的。代理只是具有功能。
【解决方案3】:

在 bean 实例化期间,读取 servlet-context.xml 并实例化具有 @Controller@Service@Repository 的 bean。

现在,当读取application-context.xml(具有&lt;tx:annotation-driven /&gt;)时,bean 已经存在,因此不会获得事务行为。使 servlet-context.xml 中的包特定于 UI (如控制器)/ 或从组件扫描中排除 Service、Repository 包。

<context:component-scan base-package="com.java.controllers"/> 

【讨论】:

    猜你喜欢
    • 2010-10-18
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2011-10-25
    • 1970-01-01
    相关资源
    最近更新 更多