2014-02-14 19 views
2

SQLException對象的「鏈」背後的語義是什麼,它與Throwable類中的getCause方法形成的類似(隱式)鏈有什麼不同?chained java.lang.SQLException實例與Throwable#getCause

由於SQLException也是Throwable,那個類的一個實例可以具有兩個這樣的「鏈:

  • 通過getNextException()呼叫的序列所定義的一個 - 直到null是最終返回的其他
  • 定義通過一系列getCause()來電 - 直到零爲止最終返回

......在這種情況下,這兩條鏈如何相互關聯?

回答

1

SQLException.setNextException(Exception)SQLException.getNextException()允許從單個方法調用中報告多個不同的SQLException。那些SQLException不是彼此的原因。

實際發生的事情非常罕見,但是說我執行一個帶有2個參數的準備插入語句。其中一個參數太長,另一個爲空,而列爲NOT NULL。數據庫可能(雖然我相信大多數數據庫不會)將這兩個錯誤都報告給驅動程序。但由於executeUpdate方法只能拋出一個SQLException,這些錯誤使用setNextException鏈接在一起。這就可以讓你找到了兩個錯誤條件

還要注意的是SQLException有一個iterator()方法,它允許您遍歷每過SQLException及其原因(即:當前SQLException,目前SQLException的所有原因,接下來SQLException如果任何等

它類似於使用getNextWarning()SQLWarning如果多個警告發生(無論同時或順序地),它們被鏈接在一起。SQLWarning不拋出,但是產生該警告對象上提供(例如Connection.getWarnings(),Statement.getWarnings()等),該方法返回f首先警告,並允許您使用getNextWarning()發現其他警告。

+0

那麼您是說SQLException#iterator方法首先執行深度優先遍歷異常樹?因爲它實際上是一棵樹,理論上SQLException實例的getCause(在某個深度)可能會返回另一個SQLException,並帶有自己的鏈式異常。現在,我只希望方法能夠在deptn(如Apache lang3 ExceptionUtils#getStackTrace中繼續挖掘#getCause方法)和廣度(沿着鏈式SQLExceptions)中對所有異常樹進行字符串化,以便我可以記錄單個全部異常包含'String'對象。 –

+0

@MarcusJuniusBrutus查看['SQLException']的源代碼(http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/sql/SQLException.java? av = f#314),它不會從原因迭代'下一個SQLException鏈'。它只會在最初的'SQLException'和迭代初始鏈中每個'SQLException'的原因鏈上遍歷'getNextException'鏈。 –

1

我想這是由於歷史原因:

  • getNextException()是存在的,因爲JDBC與Java的引入1.1
  • getCause()指出它的存在 「因爲1.4」

所以getNextException()似乎有出於兼容性原因,getCause()是更新,更一般的方式來鏈接例外。

+0

它不完全相同'getNextException()'也可以用於多個併發異常,這些異常不一定是每個其他異常引起的(儘管這種情況很少發生)。 –