讓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調用封裝

http://blog.csdn.net/sunyujia/archive/2008/05/18/2456325.aspx

我把這段程序放到了實際項目中,但是我的同事在使用的時候卻遇到了問題。如果存儲過程中這樣寫

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

 

請參見

@@ROWCOUNT

SET

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章