【问题标题】:Hibernate5, Spring 4 - org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current threadHibernate5,Spring 4 - org.hibernate.HibernateException:无法获取当前线程的事务同步会话
【发布时间】:2016-11-14 06:40:03
【问题描述】:

我们正在将项目从 Hibernate 3.6.10 升级到 Hibernate 5.2.0,但在迁移时出现错误。我在 StackOverFlow 和 Google 上浏览了很多帖子,但没有找到任何解决方案。

考虑代码参考this website。我只做了数据库连接到 PostgreSQL 数据库。

如果我在添加这些 JAR (ALL Added JAR files screenshot) 后运行此示例,除了休眠 JAR 是 3.6.10-final,它完全可以正常工作。但是,如果我为 hibernate 5 升级进行这些更改:

  1. 更改 JAR 文件添加为 Hibernate-core-5.2.1-Final.jar
  2. 将 hibernate3 文件的引用更改为 hibernate5(3 个替换;1 个在 EmployeeDao 导入中,另外 2 个在 applicationContext.xml 中)

它会抛出以下错误:

Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
at org.springframework.orm.hibernate5.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1132)
at org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:618)
at org.springframework.orm.hibernate5.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:615)
at org.springframework.orm.hibernate5.HibernateTemplate.doExecute(HibernateTemplate.java:340)
at org.springframework.orm.hibernate5.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:307)
at org.springframework.orm.hibernate5.HibernateTemplate.save(HibernateTemplate.java:615)
at hibernate.test.EmployeeDao.saveEmployee(EmployeeDao.java:12)
at hibernate.test.InsertTest.main(InsertTest.java:21)

我也进行了这些更改,但遇到了同样的错误: 1. EmployeeDao 评论:

/*HibernateTemplate template;  

public void setTemplate(HibernateTemplate template) {  
    this.template = template;  
}  */

并扩展 HibernateDaoSupport,使其提供 sessionFactory 设置器。

并将以下代码替换为:

public void saveEmployee(Employee e){  
    template.save(e);  
} 

这个:

public void saveEmployee(Employee e){  
      this.getHibernateTemplate().save(e);
}  

经过调试,我知道在 Spring-orm-4.3.1 Jar 提供的 HibernateTemplate 类中抛出了上述错误。

Here is the snapshot.

谁能帮我解决这个问题:O。我们已经在这里停留了很长时间。我很感激帮助。

【问题讨论】:

  • 以上参考链接:或图 2-i.stack.imgur.com/NwPwl.png 用于图 3-i.stack.imgur.com/Zgx5d.png
  • 首先,我不鼓励使用HibernateTemplate。请参阅此问题stackoverflow.com/questions/4067775/…。阅读接受的答案。您必须从 HibernateTemplate 迁移到 SessionFactory 和声明式事务管理。
  • @TheCoder 感谢您的回复。在这个项目中,它是如此巨大,任何新的实施都可能需要很长时间。我已经完成了提到的线程,他们说它已从 Spring 中删除?但我通过导入org.springframework.orm.hibernate5.HibernateTemplate 使用。无论如何,请尽可能回答上述问题,这就是我所需要的。谢谢。
  • 你不应该再使用HibernateTemplate,它只是为了迁移到普通的SessionFactory。旧的会话工厂确实在找不到会话时自己获得了会话,新版本需要正确的事务设置,因为它在下面使用getCurrentSession
  • @Harpreet,我明白了。但关键是,您正在从Hibernate 3.6.10 -> Hibernate 5.2.0 迁移。因此,您还必须根据需要迁移大部分代码以使用最新的休眠版本。如果您担心进行大量更改并且只想坚持使用当前代码,那么仅升级版本而不使用任何新功能(会话工厂、声明式事务管理等)是没有意义的。没有冒犯..!

标签: spring hibernate


【解决方案1】:

创建 DataSource.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">  

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>classpath:properties/database.properties</value>
    </property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

使用单独的 hibernate.xml 文件创建 sessionFactory,如下所示

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

<!-- Hibernate session factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

    <property name="dataSource">
      <ref bean="dataSource"/>
    </property>

    <property name="hibernateProperties">
       <props>
         <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
         <prop key="hibernate.show_sql">false</prop>
         <prop key="hibernate.hbm2ddl.auto">update</prop>
       </props>
    </property>

    <property name="annotatedClasses">
    <list>
        <value>com.rapidtech.rapidtechorganic.model.Lot</value>
        <value>com.rapidtech.rapidtechorganic.model.ProductAvailable</value>
        <value>com.rapidtech.rapidtechorganic.model.Client</value>
        <value>com.rapidtech.rapidtechorganic.model.Invoice</value>
        <value>com.rapidtech.rapidtechorganic.model.ProductBuyed</value>
    </list>
    </property>

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

在你的 serverl-context.xml 中包含这两个 xml 文件

<!-- Database Configuration -->
<beans:import resource="classpath:database/DataSource.xml"/>
<beans:import resource="classpath:database/Hibernate.xml"/>

然后在你的抽象类中注入 sessionFactory

@Resource
private SessionFactory sessionFactory;
public void save(Entity entity){
   Session session = sessionFactory.openSession();
   session.beginTransaction();
   session.save(entity);
   session.getTransaction().commit();
   session.close();
}

【讨论】:

  • 感谢您的回答,您实际上不必发布整个代码,我已经检查过了。需要修改示例代码 来创建 openSession,这就是您实际在做的事情,但这不是预期的答案。 HibernateTemplate 在 doExecute 方法中的session = getSessionFactory().getCurrentSession(); 行抛出错误,这意味着任何配置问题。
  • 实际上我使用的是hibernate 5和spring 4。早些时候我也遇到过同样的问题,但在将其更改为我在此处发布的代码后一切正常。
  • 确保在你的类路径中有 hibernate-entitymanager jar 文件
  • 谢谢@Tinku。是的,我明白这一点。所以我实际上告诉了你适用于我的解决方案,但它并不被所有人视为解决方案。配置需要更新。
猜你喜欢
  • 2014-12-04
  • 1970-01-01
  • 2015-04-04
  • 1970-01-01
  • 2015-03-11
  • 2015-04-11
  • 2015-09-22
  • 2014-11-29
相关资源
最近更新 更多