`

难经5:当IBatis、Hibernate混合事务时,注意你的SQL

阅读更多

【问题】

现在,在开发所谓多层JavaEE应用时,数据持久层总是不可或缺的,而“全自动型”的ORM--Hibernate,和“全手动型”的SqlMap--IBatis,就相当于是数据持久层的哥俩好。这兄弟俩各有优势,也各有缺点,总体来说,Hibernate很好很强大,但细节多,学习曲线陡峭;而IBatis很快很简单,但不能跨数据库,要自己写很多SQL,包括分页等。因此,在不少项目里,我们同时使用了这两个组件,并使用Spring来统一管理事务。

 

最近参与的一个项目,就是使用了这种方式,但是却遇到了一个意向不到的问题:有一个包含IBatisDAO和HibernateDAO操作的Service方法,执行过程中总是抛空指针异常;而且,这个异常只在Sybase数据库上测试时抛出,而用MySQL则没有问题;更奇怪的是,单独测试IBatisDAO和HibernateDAO时,不论什么数据库,均没有问题;

 

【探幽】

空指针异常抛出的位置,是在用Hibernate执行一个P对象的查询后,再查询P懒加载的一个关联对象集后抛出的。

 

反应一:这个问题,让我想到了之前碰到过的一个Sybase的问题(见难经一:http://liuu.iteye.com/admin/blogs/288660),难道又是Sybase跟Hibernate有什么不兼容?但是,由于单独测试DAO都没有问题,我否定了这个可能。

 

反应二: 是不是IBatis和Hibernate的事务混和出的问题?但是只在Sybase下碰到,就很奇怪了(没办法,这是项目的生产环境),该死的Sybase到底在闹什么别扭呢。

 

IBatis和Hibernate的混合使用,其实配置起来比较简单,网上也有很多示例,大致如下三步:只要在Spring中公用一个数据源,并配置使用同一个DataSource事务管理器,再配置允许Hibernate和IBatis使用外部的事务管理即可。再次检查这些配置,也没有看出什么异常来,而空指针异常也每次顽固的抛出,绝对重现......

 

打开Hibernate的SQL日志,我在出异常的地方反复调试,看看执行的SQL到底有什么问题:

1、执行对象P的操作查询,OK

2、执行对象P的关联集合属性(包括对象M和C)的查询,OK

3、使用对象M,OK

4、使用C对象是,却发现C依然是null,FAILED

 

问题出现在4,C对象查询后居然为空,难道2查询结果不对?

于是,我将2执行的SQL拷出来用直接连接数据库执行,却发现查询结果正常!

 

问题到底在哪?

 

我郁闷的回过头来再看日志,突然发现,2查询返回的结果只有一条记录!不对啊,刚才查询是有两条的啊,一条对应对象M,另一条对应对象C,如果只返回一条,那么C对象肯定为空了!

 

呼呼,空指针异常的原因找到了,但是,新的问题又来了,为什么Hibernate执行查询2时,只返回一条记录呢。归纳一下现在的情况:

1、这个问题只在Sybase下出现,其他数据库正常

2、HibernateDAO和IBatisDAO单独执行都没有问题

3、在执行Hibernate查询之前,执行过IBatis的SQL

4、事务边界划在Service的方法上,因此,Hibernate和IBatis执行的所有操作,都在同一个连接的同一个事务里

 

结合这四条,我的头脑映出了一条Sybase专用的限制结果集语句:“set rowcount 1”,对,应该就是它,它会限制当前连接的所有查询都只返回不多于一条的记录,而其他的数据库如MySQL之limit、Oracle之rownum、MSSQL之top(Sybase的新版本也支持top),都只对当前查询SQL有效,没有副作用。

 

可以肯定,在Sybase下,在做这个Hibernate查询之前,在执行的某个IBatis的SQL查询操作中,使用了set rowcount 1,却没有在查询后改回 rowcount的设置,从而导致后续的查询结果集都是1条,从而导致了后面的C对象为null的异常。

 

【解难】

当把问题的焦点从抛异常的HibernateDAO处,移到Service类执行该操作之前的其他IBatisDAO的操作时,通过一一排查时,很快在IBatisDAO的Sybase实现版本的某个映射配置文件中,找到了罪魁祸首:那条“set rowcount 1”语句,而在select之后,确实没有“set rowcount 0”来将rowcount复原。

 

在那条select语句后面,加上 “set rowcount 0”,再次测试Service,OK,JUnit绿条通过!!

 

【小结】

回头来看,这次碰到的看似一个小问题,找起来却费了大麻烦,归结起来有如下原因:

1、错误游离和假相:IBatis中SQL编写的错误,却在Hibernate实现的DAO中才引起异常,导致总是认为错误在后者,而想不到前者。

2、缺乏沟通和代码检查:由于一部分人用IBatis开发,一部分人用Hibernate开发,两边都不了解两个部分之于整体的关系,而单独的DAO测试,却检验不出这类问题来,因而在集成时难以真正定位问题

 

总之一句话,如果使用IBatis开发,不管有没有混合使用Hibernate,一定要注意SQL本身的检查,包括当前连接属性的设置和恢复,以及不同数据库之间的差异。

5
0
分享到:
评论

相关推荐

    难经3:Struts2,拦截器拦不住Result?

    NULL 博文链接:https://liuu.iteye.com/blog/316558

    经络学说中存在的瑕疵与疑惑

    经络学说中存在的瑕疵与疑惑,王维兵,王玉玲,目的:分析经络学说中存在的瑕疵与疑惑,为修正经络学说奠定基础。方法:以《内经》、《难经》、高校教材《经络学》等为依据,与

    “脾裹血”功能与实质的现代释义

    “脾裹血”功能与实质的现代释义,刘雅峰,王佳,经考证历史文献,结合临床实践认为,《难经》中提出的

    grpcio-1.47.0-cp310-cp310-linux_armv7l.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    小程序项目源码-美容预约小程序.zip

    小程序项目源码-美容预约小程序小程序项目源码-美容预约小程序小程序项目源码-美容预约小程序小程序项目源码-美容预约小程序小程序项目源码-美容预约小程序小程序项目源码-美容预约小程序小程序项目源码-美容预约小程序小程序项目源码-美容预约小程序v

    MobaXterm 工具

    MobaXterm 工具

    grpcio-1.48.0-cp37-cp37m-linux_armv7l.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    扁平风格PPT可修改ppt下载(11).zip

    扁平风格PPT可修改ppt下载(11).zip

    基于MATLAB实现的msk信号调制解调过程,包括发送端及接收端信号谱分析过程+使用说明文档.rar

    CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的msk信号调制解调过程,包括发送端及接收端信号谱分析过程+使用说明文档.rar 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!

    有色金属行业周报有色金属稳增长目标明确工业及贵金属价格普涨-19页.pdf.zip

    有色金属行业周报有色金属稳增长目标明确工业及贵金属价格普涨-19页.pdf

    Java_Tinker是Android的热修复解决方案库,它支持索引库和资源更新,无需重新安装apk.zip

    Java_Tinker是Android的热修复解决方案库,它支持索引库和资源更新,无需重新安装apk

    基于Python的联邦学习驾驶员状态分类设计源码

    联邦学习驾驶员状态分类设计源码:该项目基于Python开发,包含20个文件,主要使用Python语言。该项目利用VGG19、efficientnet和Resnet50等深度学习模型对驾驶员状态数据集进行分类。近期工作中,项目加入了联邦学习的方法,引入了Shapley值和激励机制,以提高模型的准确性和鲁棒性。

    番薯社区app源码分享

    比较上次: 1. 更换了图文混编显示,使用 setspan+glide 图片加载实现 2. 增加了全局主题选择 (用户自定义颜色只能实现部分对方) 3. 增加了历史记录和历史访问记录 4. 新添选择 帖子列表 样式 (简约风, 卡片风, 交流风, 西北风) 5. 除了查看帖子外,新增了 APP 界面风,用于介绍某一文件或某一 APP。 反正就逐渐向社区迈进,远离记录日常笔记 APP 越来越远了 文件后缀是.tsp 懂的拿着玩玩吧

    下雨天适合吃火锅的文案.docx

    下雨天适合吃火锅的文案.docx

    基于Swift的EasyDropDownMenu筛选排序菜单设计源码

    EasyDropDownMenu筛选排序菜单设计源码:该项目基于Swift开发,包含60个文件,主要使用Swift语言。该设计源码实现了类似美团、糯米、大众点评的筛选排序菜单,适用于iOS应用中的筛选和排序功能,以提供用户更直观、便捷的交互体验。

    520表白代码,你值得拥有

    表白代码是一种利用编程技术,通过特定的代码语言和结构来传达爱意的方式。这些代码可以通过多种方式实现,例如使用微信、网页、弹窗提示、控制台输出、图形绘制等,并且可以根据不同的场景和效果选择合适的表白方式。 以下是一些表白代码的示例和介绍: 微信表白代码:这是一种利用微信平台,通过发送包含特定代码的消息来传达爱意的方式。例如,可以使用一些有趣的代码,如“我想要两颗西柚”(实际上是“1 want to see you”,意为“我想要见你”)或者“Mg+ZnSO4==MgSO4+Zn”(意为“你的镁夺走了我的锌”,暗指“你的美丽夺走了我的心”)。 网页表白代码:通过创建一个包含特定动画、文字或图像的网页,来传达爱意。这种表白方式可以在网页上添加背景音乐、动画效果、表单提交等功能,使得表白更加生动和有趣。 弹窗提示表白代码:在打开某个网页或程序时,弹出一个包含表白信息的提示框。这种表白方式可以在用户不经意间触发,带来惊喜和感动。 控制台输出表白代码:在编程环境(如Python、JavaScript等)的控制台中输出一段表白的话语或图案。

    HTML+CSS制作的个人博客网页.zip

    如标题所述,内有详细说明

    基于MATLAB实现的杨氏双缝,光的干涉实验,基于滑动块改变参数+GUI界面+使用说明文档.zip

    CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的杨氏双缝,光的干涉实验,基于滑动块改变参数+GUI界面+使用说明文档.zip 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!

    grpcio-1.45.0-cp310-cp310-linux_armv7l.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    grpcio-1.47.0-cp39-cp39-linux_armv7l.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

Global site tag (gtag.js) - Google Analytics