java 第二次调用方法后,Hibernate Session 在 spring 事务中关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16696998/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:41:18  来源:igfitidea点击:

Hibernate Session is closed in spring transaction after calling method second time

javaspringhibernatetransactions

提问by Akhilesh

First of all I am a beginner in spring.I have created a simple Spring service that has DAO injected and transaction is managed by HibernateTransactionManager of spring, like as below.(And transaction configuration is used using annotations )

首先,我是spring的初学者。我创建了一个简单的Spring服务,注入了DAO,事务由spring的HibernateTransactionManager管理,如下所示。(使用注释使用事务配置)

@Service(value="daopowered")
public class UserServiceImplDao implements UserService
    {
    @Inject
    private UserDao userDao;


    @Override
    @Transactional
    public User autheticate( String userId, String password )
    {
    return userDao.findByIdAndPassword(userId, password);
    } 

My transaction configuration is following

我的交易配置如下

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

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

Now the problem is when I call authenticate method first time using some controller then it works fine ( does DB operations successfully) but after calling it again second time hibernate session is closed exception is coming ? Please guide me what I am doing it wrong or how to handle this scenario ? Why wont spring opens a new transaction when I call this method second time ?

现在的问题是,当我第一次使用某个控制器调用身份验证方法时,它工作正常(数据库操作是否成功),但是在第二次休眠会话关闭时再次调用它后异常即将到来?请指导我我做错了什么或如何处理这种情况?当我第二次调用此方法时,为什么 spring 不会打开一个新事务?

Exception Trace:

异常跟踪:

2013-05-22T21:04:18.041+0530 DEBUG [14208212-2] lerExceptionResolver Resolving exception from handler [com.akhi.store.controller.HomeController@5d9d277e]: org.springframework.orm.hibernate3.HibernateSystemException: Session is closed!; nested exception is org.hibernate.SessionException: Session is closed!
2013-05-22T21:04:18.044+0530 DEBUG [14208212-2] tusExceptionResolver Resolving exception from handler [com.akhi.store.controller.HomeController@5d9d277e]: org.springframework.orm.hibernate3.HibernateSystemException: Session is closed!; nested exception is org.hibernate.SessionException: Session is closed!
2013-05-22T21:04:18.044+0530 DEBUG [14208212-2] lerExceptionResolver Resolving exception from handler [com.akhi.store.controller.HomeController@5d9d277e]: org.springframework.orm.hibernate3.HibernateSystemException: Session is closed!; nested exception is org.hibernate.SessionException: Session is closed!
2013-05-22T21:04:18.046+0530 DEBUG [14208212-2] et.DispatcherServlet Could not complete request
org.springframework.orm.hibernate3.HibernateSystemException: Session is closed!; nested exception is org.hibernate.SessionException: Session is closed!
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:658)
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.convertHibernateAccessException(AbstractSessionFactoryBean.java:245)
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.translateExceptionIfPossible(AbstractSessionFactoryBean.java:224)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at com.sun.proxy.$Proxy28.findByIdAndPassword(Unknown Source)

EDIT: The DAO code

编辑:DAO 代码

@Repository
public class UserDaoImpl extends GenericHibernateDAO<User, Long>
                                implements
                                UserDao
    {

    @Override
    public User findByIdAndPassword( String id, String password )
    {

    Criteria crit = getSession().createCriteria(User.class).add(Restrictions.eq("userId",
                                            id)).add(Restrictions.eq("password",
                                                         password)).setMaxResults(1);
    List<?> list = crit.list();

    if (list.size() > 0)
        return (User) list.get(0);
    else
        return null;
    }

and getSession() implementation is

和 getSession() 实现是

protected Session getSession() {
    if (session == null) {
        session = sessionFactory.getCurrentSession();
    }

    return session;
}

Also the abstract DAO class has sessionfactory injected

抽象的 DAO 类也注入了 sessionfactory

public abstract class GenericHibernateDAO<T, ID extends Serializable>
        implements GenericDAO<T, Long> {
    private Class<T> persistentClass;

    protected Session session;

    @Autowired
    private SessionFactory sessionFactory;

回答by Sark

Your ObjectDao need a SessionFactory and the annotation Transaction. Something like this :

您的 ObjectDao 需要一个 SessionFactory 和注释事务。像这样的事情:

@Component
public class userDao{
       @AutoWired
       private SessionFactory sessionFactory;


       @Transactional
       public User findByIdAndPassword(String id , String password){
             ....
       }

       {getters and setters}

} 

Dont do that :

不要那样做:

protected Session getSession() {
    if (session == null) {
        session = sessionFactory.getCurrentSession();
    }

    return session;
}

just return the current session , the Transactional annotation is responsible for opening and closing sessions , like this :

只需返回当前会话,事务注释负责打开和关闭会话,如下所示:

protected Session getSession() {
    return  sessionFactory.getCurrentSession();
}