简体   繁体   English

带注释的Spring + Hibernate:没有Hibernate会话绑定到线程

[英]Spring + Hibernate with annotations: No Hibernate Session bound to thread

I'm new to Spring and I was trying to create a webapp with the following stack: Apache Tomcat 7, MySQL, Spring MVC, Hibernate 3 with JPA annotations. 我是Spring的新手,我正在尝试使用以下堆栈创建一个webapp:Apache Tomcat 7,MySQL,Spring MVC,带有JPA注释的Hibernate 3。

I am trying to learn by following the book "Spring in Action, Third Edition" by Craig Walls. 我正试图通过遵循Craig Walls的“Spring in Action,第三版”一书来学习。

First, I wanted to create a page that displays some entries I manually added to my DB, but it looks like my application is not capable of creating/retrieving any Hibernate Session from my SessionFactory. 首先,我想创建一个页面,显示我手动添加到我的数据库中的一些条目,但看起来我的应用程序无法从SessionFactory创建/检索任何Hibernate会话。 Here is my root cause stack trace: 这是我的根本原因堆栈跟踪:

exception

org.springframework.web.util.NestedServletException: 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
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

root cause

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
    org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
    com.nbarraille.www.dao.HibernateContactDAO.listContact(HibernateContactDAO.java:27)
    com.nbarraille.www.controllers.HomeController.showHomePage(HomeController.java:24)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:613)
    org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

And here are my concerned Classes/Config files: 这是我关心的Classes / Config文件:

My HibernateDAO: 我的HibernateDAO:

@Repository
public class HibernateContactDAO implements ContactDAO {

    private SessionFactory sessionFactory;

    @Autowired
    public HibernateContactDAO(SessionFactory sessionFactory){
        this.sessionFactory = sessionFactory;
    }

    public void addContact(Contact contact) {
        sessionFactory.getCurrentSession().save(contact);
    }

    public List<Contact> listContact() {
        @SuppressWarnings("unchecked")
        List<Contact> cl = sessionFactory.getCurrentSession().createQuery("from Contact").list();
        return cl;
    }

    public void removeContact(Integer id) {
        Contact contact = (Contact) sessionFactory.getCurrentSession().load(Contact.class, id);
        if (null != contact) {
            sessionFactory.getCurrentSession().delete(contact);
        }

    }
}

My Contact class: 我的联系课程:

@Entity
@Table(name="contacts")
public class Contact implements Serializable {
    private static final long serialVersionUID = -5389913432051078273L;

    @Id
    @Column(name="id")
    @GeneratedValue
    private int id;

    @Column(name="first_name")
    private String firstname;

    @Column(name="last_name")
    private String lastname;

    @Column(name="email")
    private String email;

    @Column(name="telephone")
    private String telephone;


    // Setters/Getters
}

My Controller class: 我的控制器类:

@Controller

    public class HomeController {

        private ContactDAO contactDAO; // I know I should pass through a service instead of accessing my DAO directly, and I usually do, but I skipped it here to simplify and try to locate the problem

        @Inject
        public HomeController(ContactDAO contactDAO){
            this.contactDAO = contactDAO;
        }

        @RequestMapping({"/", "/home"})
        public String showHomePage(Map<String,Object> model){
            model.put("contacts", contactDAO.listContact());
            return "index";
        }
    }

Here is my Context Data Config file: 这是我的Context Data Config文件:

<bean id="DBpropertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="/WEB-INF/jdbc.properties" />
    </bean>

<bean id="dataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/nbarraille" />
    <property name="username" value="root" />
    <property name="password" value="password" />
    </bean>
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.nbarraille.www.core" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

    <!-- Adds an advisor to any bean annotated with @Repository so that any platform-specific exception
         are caught and then rethrown as one of Spring's unchecked data access exceptions -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

Here is my Dispatcher Servlet config: 这是我的Dispatcher Servlet配置:

<mvc:resources mapping="/resources/**"
                   location="/resources/" />

<mvc:annotation-driven />

<context:component-scan base-package="com.nbarraille.www" />

<bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver" />

<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles-def.xml</value>
            </list>
        </property>
    </bean>

    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:messages" />
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

    <bean id="localeChangeInterceptor"
        class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="lang" />
    </bean>

    <bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="en"/>
    </bean>

And finally, here is my web.xml file: 最后,这是我的web.xml文件:

<servlet>
    <servlet-name>nbarraille</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

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

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/nbarraille-service.xml
        /WEB-INF/nbarraille-data.xml
        /WEB-INF/nbarraille-security.xml
    </param-value>
</context-param>

You don't seem to have transaction configured yet... you can add the following into your Context Data Config file:- 您似乎还没有配置事务...您可以将以下内容添加到Context Data Config文件中: -

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

<tx:advice id="txAdvice">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:advisor pointcut="execution(* YOUR.PACKAGE..*.*(..))" advice-ref="txAdvice" />
</aop:config>

Change YOUR.PACKAGE to your actual package name, for example:- YOUR.PACKAGE更改为您的实际包名称,例如: -

execution(* com.project..*.*(..))

This is one lazy way to wrap all your methods in your project with transaction. 这是使用事务将所有方法包装在项目中的一种懒惰方法。

By the way, if you are going to lazily query your Hibernate domain objects (ex: parent.getChildren() ) in your view, then I would highly suggest you to add this into your web.xml:- 顺便说一句,如果你要在视图中懒洋洋地查询你的Hibernate域对象(例如: parent.getChildren() ),那么我强烈建议你将它添加到你的web.xml中: -

<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

This filter extends Hibernate session to the view. 此过滤器将Hibernate会话扩展到视图。

I have the same problem today. 我今天也有同样的问题。 It is connected with hibernate unit of work conception and db transaction. 它与hibernate工作概念和db事务连接。 So shortly speaking. 很快就说了。 If you use framework spring it has own transaction manager and session factory impelementation. 如果使用框架弹簧,它有自己的事务管理器和会话工厂的实例。 But if you would like to use it you shuld remeber to configure it but also correct order of the adnotation. 但是如果你想使用它,你需要记住配置它,但也要更正注释的顺序。 Your service should be @Transactional, your DAO should be @Repository and DAO use @Entity beans. 你的服务应该是@Transactional,你的DAO应该是@Repository,DAO使用@Entity bean。 So if you would use spring implementation of transaction manager you should use your transactional service in your controller ;) it is quite simple and in your dao you do sessionfactory.getCurrentSession() to get session ;) 因此,如果你要使用事务管理器的spring实现,你应该在你的控制器中使用你的事务服务;)它很简单,在你的dao中你做sessionfactory.getCurrentSession()来获取会话;)

For what it's worth ... run into this as well, after much looking had to modify part of web.xml: 对于它的价值......在遇到很多需要修改web.xml的部分之后,也要遇到这个问题:

    <filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>singleSession</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

... specifically had to set singleSession to true ...特别需要将singleSession设置为true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring + Hibernate:没有Hibernate Session绑定到线程 - Spring + Hibernate: No Hibernate Session bound to thread Spring MVC - 没有Hibernate Session绑定到线程 - Spring MVC - No Hibernate Session bound to thread Spring + Hibernate带注释:如何将Hibernate Session绑定到线程? - Spring + Hibernate with annotations: how to bind Hibernate Session to thread? Spring + Hibernate异常:没有绑定到线程的hibernate会话 - Spring+Hibernate Exception : No hibernate session bound to thread 没有Hibernate Session绑定到线程异常 - No Hibernate Session bound to thread exception HibernateException:没有 Hibernate Session 绑定到线程 - HibernateException: No Hibernate Session bound to thread HibernateSystemException:没有 Hibernate Session 绑定到线程 - HibernateSystemException: No Hibernate Session bound to thread Hibernate异常:没有Hibernate Session绑定到线程 - Hibernate exception: No Hibernate Session bound to Thread Hibernate 和 Spring3 事务管理注释-配置问题:休眠异常:没有 Hibernate Session 绑定到线程 - Hibernate and Spring3 Transaction Management Annotation-Configuration problems: Hibernate-Exception: No Hibernate Session bound to thread Spring MVC + Hibernate:没有Hibernate Session绑定到线程,配置不允许在这里创建非事务性的 - Spring MVC + Hibernate: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM