2010-07-28 115 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