zoukankan      html  css  js  c++  java
  • 让Hibernate和触发器协同工作

     

     

     
     

    Sql Server触发器和hibernate一起使用时经常报类似如下错误

    Batch update returned unexpected row count from update [0];

    这个问题困扰了我半年,不止上面的错误还有其他类似的错误,半年内一直很郁闷,半年是什么概念真是晕倒,曾经也百度过但是没有解决方案,很多回答都是说hibernate和sqlserver 兼容不好,或者说程序是oo的不能用触发器,但这些都不是解决问题的方法,今天又遇到同事写的程序有这个问题,因为这个问题,我已经不将hibernate和sqlserver触发器一起使用了,但是遇到了就得解决,仔细分析这段话

    Batch update returned unexpected row count from update [0];

    批量保存失败,因为返回的行数和预期的不一样,从语意上来看hibernate做的是对的,因为如果只写一句session.update(u);hibernate是有理由做校验的,这时我在想如何能让hibernate感知不到触发器的工作,前几天写存储过程使用临时表的一个小技巧给了我提示.

    前段时间我写个了针对存储过程的java调用封装

    我把这段程序放到了实际项目中,但是我的同事在使用的时候却遇到了问题。如果存储过程中这样写

    select * into #t from table

    在java中利用我封装的类无法取得最后返回的结果集,起初我认为是我封装的程序有问题,后来查看了前人写的存储过程发现了线索,原来少了一句set nocount on,这句话起关键作用。

    从单词上看,意思是不计数返回的行数,当时我还没有预见到这句话可以解决hibernate和触发器协作的问题,直到今天我突然联想到了这件事,因为这几天还一直在做数据库性能优化,set nocount on还可以起到性能优化的作用。

    所以今天再次遇到hibernate和触发器冲突的问题时,我突然想到了set nocount on,有了这句话java程序就感知不到返回的行数了也自然谈不上unexpected的问题了。

    至于hibernate和触发器一起工作的其他问题我目前还没发现有障碍性的,基本通过编程都可以解决,至于session同步,刷新就可以了。

    为了说明问题还是发小段代码

    SET QUOTED_IDENTIFIER ON 
    GO
    SET ANSI_NULLS ON 
    GO
    Create  TRIGGER [Syj_User_Triger] ON [dbo].[Syj_User] 
    FOR INSERT, UPDATE, DELETE 
    AS
    set nocount on  --不加这句话hibernate会报错,因为下面的update操作计数返回的值>1
    update authors set state=state 
    GO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO
    SET NOCOUNT

    最后看下sqlserver帮助里面的解释

    SET NOCOUNT

    使返回的结果中不包含有关受 Transact-SQL 语句影响的行数的信息。

    语法

    SET NOCOUNT { ON | OFF }

    注释

    当 SET NOCOUNT 为 ON 时,不返回计数(表示受 Transact-SQL 语句影响的行数)。当 SET NOCOUNT 为 OFF 时,返回计数。

    即使当 SET NOCOUNT 为 ON 时,也更新 @@ROWCOUNT 函数。

    当 SET NOCOUNT 为 ON 时,将不给客户端发送存储过程中的每个语句的 DONE_IN_PROC 信息。当使用 Microsoft® SQL Server™ 提供的实用工具执行查询时,在 Transact-SQL 语句(如 SELECT、INSERT、UPDATE 和 DELETE)结束时将不会在查询结果中显示"nn rows affected"。

    如果存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。

    SET NOCOUNT 设置是在执行或运行时设置,而不是在分析时设置。

    权限

    SET NOCOUNT 权限默认授予所有用户。

    示例

    下例在 osql 实用工具或 SQL Server 查询分析器中执行时,可防止显示有关受影响的行数的信息。

    USE pubs
    GO
    -- Display the count message.
    SELECT au_lname 
    FROM authors
    GO
    USE pubs
    GO
    -- SET NOCOUNT to ON and no longer display the count message.
    SET NOCOUNT ON
    GO
    SELECT au_lname 
    FROM authors
    GO
    -- Reset SET NOCOUNT to OFF.
    SET NOCOUNT OFF
    GO
  • 相关阅读:
    numpy基本使用2
    python 继承 多态
    动态规划算法题(5题)
    利用栈非递归实现块排
    数据结构
    对Node的优点和缺点提出了自己的看法?
    前后端交互流程,如何进行交互
    Web App、Hybrid App与Native App的设计差异
    什么叫优雅降级和渐进增强?
    常用博客
  • 原文地址:https://www.cnblogs.com/zengda/p/4554137.html
Copyright © 2011-2022 走看看