【问题标题】:Autowired Hibernate Template lost session in when used in threadsAutowired Hibernate Template 在线程中使用时丢失会话
【发布时间】:2013-01-19 02:48:47
【问题描述】:

我正在开发一个 spring hibenrate 应用程序并卡在一个点上。 我只有 1 个控制器,只有一项服务。服务更新数据库中的数据并将更新后的 id 返回给客户端并启动线程。

    final Template template = templateBL.getTemplateById(Long.valueOf(templateId));

    Long templateStatusId = templateBL.updateTemplateStatus(template);
    Thread thread = new Thread(templateBL.setTemplate(template, templateStatusId));
    thread.start();
    return templateStatusId;

在 thread.start() 上我得到这个错误

Exception in thread "Thread-8" org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)
at org.hibernate.impl.SessionImpl.getBatcher(SessionImpl.java:297)
at org.hibernate.loader.Loader.doQuery(Loader.java:770)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
at org.hibernate.loader.Loader.loadCollection(Loader.java:2082)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:62)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:628)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1853)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:369)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272)

我正在使用休眠模板自动装配并在我的 DAO 层上应用@transactional。我的配置是:

 <bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <!-- currently set to UPDATE -->
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
 <bean>
 <bean id="transactionManager" 
     class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
          <property name="sessionFactory" ref="sessionFactory" /> 
 </bean>

我没有得到可能出错的地方。请帮忙。

【问题讨论】:

  • 事务管理器在哪里?
  • 能否显示更多代码(例如sql查询)
  • @ArunPJohny
  • @AlekseiBulgak hibernateTemplate.save(templateStatus); TemplateStatus templateStatus = (TemplateStatus) hibernateTemplate.getSessionFactory().getCurrentSession().get(TemplateStatus.class, id);结果 = hibernateTemplate.find(FROM_TEMPLATE_STATUS+(String)whereClause);
  • 我确定缺少线程所需的一些配置,当我在没有线程的情况下使用它时,应用程序运行成功且没有任何错误

标签: java multithreading spring hibernate sessionfactory


【解决方案1】:

Hibernate 会话不是广告安全的,不能由多个线程使用。如果你启动一个新线程,这个新线程应该从会话工厂获得一个新会话。如果将实体传递给新线程,则应首先将实体从会话中分离出来。

否则,正如您的代码所做的那样,任何初始化惰性集合的尝试都会调用会话中的方法。会话将被关闭(从第一个线程),导致您收到异常,或者不会,但是您将在两个线程之间进行共享会话,这将导致各种随机问题。

【讨论】:

  • 感谢回复 JB,但我正在自动装配休眠模板,我想它会自行管理会话。 @Autowired HibernateTemplate hibernateTemplate;
  • 是的,但您似乎正在将附加实体从一个线程传递到另一个线程。附加的实体链接到在第一个线程中打开的会话。
  • @HimanshuArora 请将其标记为已回答,以免出现在未回答部分
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 2013-10-21
  • 1970-01-01
  • 2016-07-09
  • 2017-09-20
  • 2011-08-12
  • 2013-06-28
相关资源
最近更新 更多