本周是时候将我们的代码库升级到最新的Hibernate 4.x了。 我们推迟了迁移(仍在Hibernate 3.3上),因为3.x分支的较新维护版本需要对API进行一些更改,这些更改显然仍在不断变化中。 一个示例是UserType API,该API仍然存在缺陷,将在Hibernate 4中完成。迁移非常顺利。 使UserType适应新界面非常简单。 到处都有一些刺激,但没有痛苦。

需要注意的是Spring集成。 如果您以前将Spring与Hibernate结合使用,则将使用LocalSessionFactoryBean (或AnnotationSessionFactoryBean )创建SessionFactory 。 对于休眠4
在自己的程序包中有一个单独的程序:org.springframework.orm。 hibernate4而不是org.springframework.orm。 休眠3 。 hibernate 4包中的LocalSessionFactoryBean将同时用于映射文件和带注释的实体,因此两种样式都只需要一个。

升级完成后,我们的所有测试都在运行,并且使用本地Hibernate事务管理器在Tomcat上的应用程序也运行良好。 但是,当使用JTA事务(和Spring的JtaTransactionManager )在Glassfish上运行时,在调用sessionFactory.getCurrentSession()时,我们得到了“未找到当前线程的会话”

因此,似乎我错过了与JTA配置有关的内容。 像通常使用Spring-Hibernate集成一样,让Spring驱动事务。 您指定一个事务管理器,Spring确保所有资源都已在事务管理器中注册,并最终调用提交或回滚。 Spring将与Hibernate集成,因此可确保在事务提交之前刷新会话。

使用hibernate 3和hibernate 3 Spring集成时,会话绑定到本地线程。 此技术使您可以使用sessionFactory.getCurrentSession()获取活动事务中任何位置的打开会话。 本地HibernateTransactionManagerJtaTransactionManager都是这种情况。 但是,从hibernate 4集成开始,hibernate会话将绑定到当前正在运行的JTA事务。

从用户的角度来看,什么都没有改变,因为sessionFactory.getCurrentSession()仍会完成其工作。 但是,当运行JTA时,这意味着Hibernate必须能够查找事务管理器以能够向当前正在运行的事务中注册会话。 如果您来自带有Spring的Hibernate 3,这是新的,实际上,您不必在Hibernate SessionFactory (或LocalSessionFactoryBean )配置中配置任何与事务有关的内容。 事实证明,通过Hibernate 4 Spring集成,事务管理器查找配置实际上是由hibernate完成的,而不是由Spring的LocalSessionFactoryBean完成的 。 解决方案非常简单。 将其添加到Hibernate( LocalSessionFactoryBean )配置中解决了我们的问题:

<prop key="hibernate.transaction.jta.platform">
org.hibernate.service.jta.platform.internal.SunOneJtaPlatform
</prop>

然后,应将“ SunOneJtaPlatform”替换为反映您的容器的子类。

有关可用的子类,请参阅API文档 。 此类实际上是在告诉Hibernate如何为您的环境查找事务管理器。 如果您不进行配置,则Hibernate不会将会话绑定到任何东西,因此不会引发异常。 还有一个属性:

hibernate.current_session_context_class

它应该指向org.springframework.orm.hibernate4.SpringSessionContext ,但这是由LocalSessionFactoryBean自动完成的,因此无需在配置中指定它。

解决了我的“当前会话未找到会话”问题后,还有另一个问题。 成功提交事务后,将看不到对事务内部的数据库所做的更改。 经过一番研究,我发现没有人在调用session.flush() 。 在进行hibernate 3集成时,注册了SpringSessionSynchronization ,它将在事务提交之前(在beforeCommmit方法中)调用session.flush( )。

在hibernate 4集成中,注册了SpringFlushSynchronization顾名思义 ,它还将执行刷新。 但是,这仅在TransactionSynchronization的实际“刷新”方法中实现,并且永远不会调用此方法。

我在Spring Bugtracker上对此提出了一个问题 ,其中包括两个示例应用程序,它们清楚地说明了该问题。 第一个使用的是Hibernate 3,另一个使用的是完全相同的应用程序,但是这次使用的是hibernte4。第二个将显示实际上没有任何信息持久化到数据库中(两个应用程序都在最新的Glassfish 3.1.2下进行了测试)。似乎正在创建一个环绕@Transactional注释的冲洗Aspect。 使用order属性,可以命令在刷新Aspect之前应用事务注释。 这样,您的Aspect仍在事务内部运行,并且能够刷新会话。 它可以通过注入SessionFactory (一种方式或另一种方式)然后调用sessionFactory.getCurrentSession()。flush()来以正常方式获取会话。

<tx:annotation-driven order="1"><bean id="flushinAspect" clas="..."><property name="order" value="2">
</property></bean>
</tx:annotation-driven>

或者,如果使用注释配置:

@EnableTransactionManagement(order=1)

更新:

关于此问题有一些反馈。 事实证明,这似乎不是Spring Hibernate集成中的错误,而是缺少的Hibernate配置元素。 显然,“ hibernate.transaction.factory_class”需要设置为JTA,默认值为JDBC,它依赖于Hibernate Transaction API进行显式事务管理。 通过将此设置为JTA,休眠将注册必要的同步,该同步将执行刷新。 见春
https://jira.springsource.org/browse/SPR-9404

更新2:

事实证明,在按照上一个问题建议的配置进行纠正后,仍然存在问题。 我将不重复任何事情,您可以在我在此处提交的第二个错误条目中找到详细信息: https : //jira.springsource.org/browse/SPR-9480它基本上可以归结为在JTA场景中在配置了JtaTransactionFactory的情况下,hibernate不会检测到它在事务中,因此将不执行中间刷新。 配置了JtaTransactionFactory之后,您应该通过Hibernate API而不是外部(在我们的例子中为Spring)机制来控制事务。 副作用之一是在某些情况下您可能正在读取陈旧的数据。

例:

//[START TX1]
Query query = session.createQuery('from Person p where p.firstName = :firstName and p.lastName = :lastName');
Person johnDoe = (Person)query.setString('firstName','john').setString('lastName','doe').uniqueResult();
johnDoe.setFirstName('Jim');
Person jimDoe = (Person)query.setString('firstName','jim').setString('lastName','doe').uniqueResult();
//[END TX1]

发生的情况是,在第5行执行第二个查询时,hibernate应该检测到它应该刷新对第4行的附加实体所做的先前更新(将名称从“ john”更新为“ jim”)。 但是,由于休眠不知道它在一个活动事务中运行,因此中间刷新不起作用。 在事务提交之前,它将仅刷新一次。 这会导致数据过时,因为第二个查询将找不到“ jim”,而是返回null。 解决方案(请参阅问题中Juergen Hoeller的答复)是将hibernate.transaction.factory_class配置为org.hibernate.transaction.CMTTransactionFactory 。 刚开始我有点怀疑,因为CMT使EJB容器成为现实。 但是,如果您阅读有关CMTTransaction的Java文档,则确实有道理:

/*** Implements a transaction strategy for Container Managed Transaction (CMT) scenarios.  All work is done in* the context of the container managed transaction.** The term 'CMT' is potentially misleading; the pertinent point simply being that the transactions are being* managed by something other than the Hibernate transaction mechanism.** Additionally, this strategy does *not* attempt to access or use the {@link javax.transaction.UserTransaction} since* in the actual case CMT access to the {@link javax.transaction.UserTransaction} is explicitly disallowed.  Instead* we use the JTA {@link javax.transaction.Transaction} object obtained from the {@link TransactionManager}

之后,一切似乎都正常。 综上所述,如果您希望休眠状态通过UserTransaction管理JTA事务,则应使用JtaTransactionFactory。 在这种情况下,您必须使用Hibernate API来控制事务。 如果还有其他人管理事务(Spring,EJB容器……),则应改用CMTTransactionFactory。 然后,通过使用javax.transaction.TransactionManager检查活动的javax.transaction.Transaction,Hibernate将恢复为注册同步。 如果弹出任何其他问题,我将相应地更新此条目。

参考:在Koen Serneels –技术博客博客上,我们的JCG合作伙伴 Koen Serneels 通过Spring集成从Hibernate 3迁移到4 。

翻译自: https://www.javacodegeeks.com/2013/03/migrating-from-hibernate-3-to-4-with-spring-integration.html

通过Spring集成从Hibernate 3迁移到4相关推荐

  1. (转)为Spring集成的Hibernate配置二级缓存

    http://blog.csdn.net/yerenyuan_pku/article/details/52896195 前面我们已经集成了Spring4.2.5+Hibernate4.3.11+Str ...

  2. Spring 4 MVC+Hibernate 4+MySQL+Maven使用注解集成实例

    Spring 4 MVC+Hibernate 4+MySQL+Maven使用注解集成实例 转自:通过注解的方式集成Spring 4 MVC+Hibernate 4+MySQL+Maven,开发项目样例 ...

  3. Liferay7 BPM门户开发之5: Activiti和Spring集成

    参考文档: https://github.com/jbarrez/spring-boot-with-activiti-example https://github.com/sxyx2008/sprin ...

  4. JBPM4.4_jBPM4.4应用(与Spring集成自行控制事务等)

    1. jBPM4.4应用 1.1. 与Spring集成(jBPM4.4 Developers Guide, Chapter 17. Spring Integration) 1.1.1. 在jbpm.c ...

  5. java 集成grizzly_java – 与Jersey和Spring集成Grizzly2.2.X

    我已经成功地将Grizzly v2.1.9与Jersey和 Spring集成在一起.但是在尝试将Grizzly迁移到版本2.2.19时无法使其工作. Grizzly v2.1.9的原始代码如下. Ht ...

  6. jbpm 4.3 与 spring 集成

    jbpm4.2与spring集成有点问题,直接跟据它自己的"开发指南"提供的方法是不能集成的.在官网查到的信息是发布4.2时,忘记更新集成spring的文件.不过4.3已经把该bu ...

  7. Spring集成MyBatis框架

    Spring集成MyBatis框架 Java在写数据库查询时,我接触过四种方式: 1.纯Java代码,引用对应的数据库驱动包,自己写连接与释放逻辑(可以用连接池) 这种模式实际上性能是非常不错的,但是 ...

  8. JBoss 4.2.x Spring 3 JPA Hibernate教程第2部分

    我们将继续有关Spring 3 , Hibernate , JPA和JBoss 4.2.x – 4.3集成的教程 . 最后一步是创建一个Spring服务,以向最终用户公开功能. 我们必须创建一个接口类 ...

  9. Spring中配置Hibernate事务的四种方式

    2019独角兽企业重金招聘Python工程师标准>>> 为了保证数据的一致性,在编程的时候往往需要引入事务这个概念.事务有4个特性:原子性.一致性.隔离性.持久性. 事务的种类有两种 ...

最新文章

  1. 【linux】Valgrind工具集详解(十五):Callgrind(性能分析图)
  2. windows服务程序设置为自动 重启后又变为手动启动_系统小技巧:解决Windows无法正常关机的问题...
  3. 最完整代码的用php备份mysql数据库
  4. 刘云鹏:大数据,让我离生活更近 | 优秀毕业生专访
  5. ql的python学习之路-day10
  6. mysql 日志丢失_失而复得数据库日志文件丢失后的恢复
  7. Hash查找的基本原理及实现
  8. UVA 11995 I Can Guess the Data Structure! STL
  9. python中break、continue 、exit() 、pass终止循环的区别
  10. cus.crm.notes.Component.extend(cus.crm.notes.ext.Component, {
  11. android怎么让图片显示在button上面_网上的图片不知道怎么批量下载?python教你怎么把网站上面的图片都爬下来...
  12. Stream将List转换为Map
  13. Python核心编程(第二版)【人民邮电出版社】
  14. 快用苹果助手安装失败_最新建行信用卡调额失败后的抓包详细教程
  15. 高中生该怎样自学编程?
  16. Processing 自动贪吃蛇脚本
  17. python3爬取网易云歌曲,利用python3爬取网易云周杰伦所有专辑,歌曲,评论,并完成可视-站长资讯中心...
  18. 【Windows 11】终端美化配置(优化)
  19. oracle调用web severs,Oracle调用C#开发web services
  20. EMI(干扰)和EMS(产品抗干扰和敏感度)。

热门文章

  1. matlab盒子分形维数_分形:盒子维数
  2. rabbitmq启动失败-报Failed to load advanced configuration file解决方法
  3. ReviewForJob——快速排序(基于插入排序)+快速选择(快速排序变体)
  4. MySQL优化(一):表结构优化
  5. 查看oracle会话和进程_带有Oracle Digital Assistant和Fn Project的会话式UI。 第三部分,迁移到云...
  6. graphql_GraphQL在Wildfly群上
  7. Java中的复合设计模式
  8. 那是两个小时我不会回来
  9. 使用Open Liberty的开发模式最大程度地缩短周转时间
  10. 如何用Java编写类似C的Sizeof函数