如何在休眠中记录失败的sql?
Posted
技术标签:
【中文标题】如何在休眠中记录失败的sql?【英文标题】:How to log failed sql in hibernate? 【发布时间】:2019-07-08 04:07:47 【问题描述】:我正在使用 spring-data-jpa 构建一个 SpringBoot 应用程序。我知道如何从这个问题记录所有 sql。 How to print a query string with parameter values when using Hibernate
但如果我只想记录失败的 sql 怎么办?
【问题讨论】:
你没有在相应的 SQLException 中得到那些吗? 我得到了异常,它只是告诉我xx
在插入大量记录时不能为空,我需要调试哪个抛出了这个异常。
【参考方案1】:
有两种选择:
-
使用参数值配置 sql 日志记录。禁用 jdbc 批处理并通过休眠方式启用刷新。
添加调试 JDBC 驱动程序,例如 p6spy,其功能或多或少与上述完全一致。
首先,我们来分析问题,将查询类型拆分为 SELECT 和 INSERT/UPDATE 查询。
-
SELECT 查询,默认情况下您已开启刷新。因此,当发生错误时,您可以确切地知道哪个查询失败了。
INSERT/UPDATE 查询,这里的事情变得很棘手,因为您的刷新将被关闭并且您有查询批处理,这意味着当您首先运行查询时它会延迟。其次,它与其他不相关的查询打包在一起,第三,Hibernate 可能会重新排序它们。所以简短的回答是,如果你单独使用休眠,这对于 INSERT/UPDATE 是不可行的。
解决您的问题需要做两件事: 1. 它应该记录带有参数值的查询。这可以通过以下方式完成:
# logs the SQL statements
log4j.logger.org.hibernate.SQL=debug
# Logs the JDBC parameters passed to a query
log4j.logger.org.hibernate.type=trace
2。解决方案需要禁用查询的批处理,否则你会得到一堆 SQL 但你不知道究竟哪个 SQL 是有问题的。
hibernate.jdbc.batch_size=1
不确定这是否足以完全禁用批处理,但您需要找出答案。
或者,您可以使用为 DEBUG 设计的 jdbc 驱动程序。这将是 p6spy 驱动程序,它可以选择刷新每条 SQL 语句,这正是您想要的。
这里需要设置autoflush=true
配置参数,保证每一条sql语句都立即刷新到数据库中。
https://p6spy.readthedocs.io/en/latest/configandusage.html
【讨论】:
【参考方案2】:这会为您提供多个日志条目。就我而言,这是不受欢迎的。 这是我的解决方案:
-
依赖 net.ttddyy:datasource-proxy:1.6
在 Spring 配置中包装数据源
@Bean
public DataSource dataSource()
return ProxyDataSourceBuilder.create(originalDatasource())
.logQueryBySlf4j(FLF4JLogLevel.DEBUG).build();
-
编写您自己的 LogAppender - 在这里您可以过滤日志事件,因此您可以过滤即仅用于插入或执行失败
public class SQLAppender extends AppenderBase
[...]
@Override
protected void append(ILoggingEvent eventObject)
[...]
-
配置 logback.xml
<appender name="mysqlAppender" class="com.my.SQLAppender" >
</appender>
<logger name="net.ttddyy.dsproxy.listener.logging.SLF4JQueryLoggingListener" level="DEBUG"\>
<appender-ref ref="mySQLAppender"/>
</logger>
【讨论】:
以上是关于如何在休眠中记录失败的sql?的主要内容,如果未能解决你的问题,请参考以下文章