我在hibernate中遇到会话问题:
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)
我已经阅读过有关此问题的内容,但解决方案在我的情况下无效。
我的Dao课程:
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);
}
}
根context.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,但仍然出现错误:
DAO:
@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);
}
}
UserService:
@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";
}
}
答案 0 :(得分:7)
正在发生的事情是servlet-context.xml
覆盖了root-context.xml
中的bean,因为它为包含component-scan
类的程序包声明了@Repository
。在servlet-context.xml
中,您有
<context:component-scan base-package="com.myportal.portal" />
当您的HibernateDao
班级位于com.myportal.portal.model
时。此ApplicationContext
将创建一个HibernateDao
bean ,无需事务管理,因为它没有<tx:annotation-driven>
。 HibernateDao
中自动装配的@Controller
bean就是这个,而不是来自root-context.xml
(具有事务管理)的bean。
要解决此问题,您需要先添加
<context:component-scan base-package="com.myportal.portal.model" />
到root-context.xml
并删除<context:annotation-config/>
(这是多余的)。然后,您想要将component-scan
中的servlet-context.xml
修改为更具体的,不包含@Repository
类的包
<context:component-scan base-package="com.myportal.portal.controllers" />
该包将包含您的@Controller
类。您也不需要<context:annotation-config>
。
答案 1 :(得分:0)
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
这意味着该线程中没有当前事务。
当你纠正我的时候,这个类是用@Transactional注释的,但我发现它没有实现一个接口。如果您在没有实现接口的情况下注释控制器时,生成的代理可能不会公开注释。
答案 2 :(得分:0)
在bean实例化期间,servlet-context.xml
被读取,并且@Controller
,@Service
,@Repository
的bean被实例化。
现在,当application-context.xml
(具有<tx:annotation-driven />
)被读取时,bean已经存在,因此不会获得事务行为。在servlet-context.xml
中使用特定于UI的包,如控制器/或从组件扫描中排除服务,存储库包。
<context:component-scan base-package="com.java.controllers"/>