2010-07-28 73 views
0

當發生org.hibernate.JDBCException(或此異常的子類型)時,sql語句在Stacktrace中不可見。爲什麼org.hibernate.JDBCException不在堆棧跟蹤中打印sql語句

例如,如果我執行與休眠以下SQL語句(在Oracle DB不具有表或視圖「nonexsiting」):

session.createSQLQuery("select * from nonexisting").list(); 

我碰到下面的堆棧跟蹤:

org.hibernate.exception.SQLGrammarException: could not execute query 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90) 
    ... 
Caused by: java.sql.SQLSyntaxErrorException: ORA-00942: Table or view does not exist 
    ... 

SQL語句未顯示在堆棧跟蹤中,但是Exception對象具有存儲的信息並且可以通過exception.getSQL()訪問。如果這個信息在堆棧跟蹤中可用,它將極大地加快調試速度。

任何人有一個想法,爲什麼這個信息不可用在堆棧跟蹤?或者如何在堆棧跟蹤中啓用此信息的輸出?

通過Hibernate的版本,我用這個例子的方法是3.3.1

+0

將信息導入堆棧跟蹤的一種方式是重新拋出異常,並將拋出的異常信息中的sql語句放入重新拋出異常的「消息」部分。 儘管如此,我仍然沒有看到爲什麼默認情況下沒有這樣做...... 例如:throw new JDBCException(e.getMessage()+「」+ e.getSQL(),e.​​getSQLException(),e.​​getSQL ) 我仍然沒有看到沒有理由爲什麼這不是默認做的... – hochraldo 2010-07-28 11:51:40

回答

0

因爲它是如何得到落實,這不是。見HB-1055

Spring和實現PersistenceExceptionTranslator的類可能會提供更接近您的期望的內容。

+0

感謝帕斯卡的答案。至於我不支持HB-1055,這是關於捕獲SQL語句並通過jdbcexception.getSQL()提供這些信息的。然而,我的問題更多的是爲什麼在打印堆棧跟蹤時未使用此方法,因爲這將是一個非常有價值的信息。 – hochraldo 2010-07-29 06:28:59

+0

@ hochraldo:因爲Gavin King選擇不將SQL語句放在'message'中,因爲這不是他實現它的方式。 – 2010-07-29 06:38:39

+0

好吧,明白了。仍然會很有趣,知道爲什麼加文決定不把這些信息放在堆棧跟蹤中... – hochraldo 2010-07-29 06:57:25

2

我認爲這可能是一個安全問題。如果將sql語句添加到堆棧跟蹤中,可能會將其發佈給用戶,因此請向他提供有關表名稱和列的信息。如果你的應用程序容易受到sql注入攻擊,這對入侵者來說是一個非常大的好處。

+0

從來沒有考慮過這一點,但是這對我來說似乎很明顯,謝謝你的洞察。 – hochraldo 2010-08-03 06:13:23

+0

我不同意**一把刀並不是一件壞事,只是因爲有人可能會被它殺死**在日誌中引起(惡意的)SQL(通常無法被最終用戶訪問)的好處是一個正在運行的生產系統(和測試系統等)極其有用,這些問題可能很難或根本無法重複,並且啓用所有SQL的日誌記錄似乎不是一個好的選擇。通過'g獲得它etSQL()'明確地(也用於日誌記錄)。如果一些開發者這樣做 - 無論如何它不會在大多數情況下損害安全或政治。 – 2015-09-03 07:36:10