如何禁用 Hibernate 的 SHOW WARNINGS?

How do I disable SHOW WARNINGS from Hibernate?

在 MySQL 中使用 Hibernate (4.3.8),我注意到 activity 日志中有一堆 SHOW WARNINGS 语句占用了相当大的带宽:

我四处搜索了一下,这是一个很常见的问题(for example) that can apparently be resolved by (and that solution is confirmed implemented 至少从 4.3.6 开始)。

问题是,我实际上不知道该怎么做。我对 Hibernate 的了解只是使用它所必需的最低限度。之前链接的 post 通过编辑 logback.xml 中的 Logback 设置解决了它,但我没有使用 Logback。我正在使用所有默认设置:

所以我实际上不确定该怎么做。这是我的配置文件:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">    
<hibernate-configuration>    
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/xxxxx</property>
        <property name="connection.username">xxxxx</property>
        <property name="connection.password">xxxxx</property>      
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.isolation">2</property>
        <property name="connection.pool_size">10</property>
        <property name="current_session_context_class">thread</property>
        <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <!-- <property name="show_sql">true</property> -->
        <!-- <property name="hbm2ddl.auto">create</property> -->
        <mapping resource="hibernate.hbm.xml"/>     
    </session-factory>    
</hibernate-configuration>

这是构建路径中的依赖项;有 Jettison 和 Joda,MySQL 驱动程序,然后是 Hibernate 的 required 依赖目录中的所有内容,没有别的:

在这种(默认设置)情况下,如何提高日志级别或禁用 [​​=11=]? This mentions "log categories of interest" but I'm not sure how those relate to the configuration file. This page 在 "Logging" 部分之外没有记录任何与日志相关的属性,其中提到了 SLF4J,但显然我没有使用 SLF4J(我怎么可能,因为它不在我的类路径中)。

好的。我得到了这个并在这个过程中学到了很多东西。


TL;DR:

在以下假设下...

  • 没有显式配置日志记录选项。
  • class路径中唯一与日志相关的 JAR 是 jboss 日志记录的(即没有 slf4j、log4j 等)。

... Hibernate 将automatically select JDK logging via JBoss Logging, and the java.util.logging 设施用于控制日志级别。因此,在根记录器级别将所有 JDK 日志的日志级别设置为 SEVERE(无论您在 Hibernate 初始化之前还是之后执行此操作都无关紧要,请参见下文)成功停止 SHOW WARNING 命令:

LogManager.getLogManager().getLogger("").setLevel(Level.SEVERE);

但是,这是一种霰弹枪方法,它为 所有 注册的 Logger 设置日志级别,它们的级别设置为 null(继承自parent).


JDK 记录笔记

我通过以下方式得出上述解决方案:

  1. 阅读 the logging doc 几次,直到它沉没,并将该信息与我的 class 路径中的内容相关联,证据表明 JDK 日志记录正在使用中。
  2. 查看了 LogManager#getLoggerNames() 中的记录器名称列表。来自Hibernate的有不少,这证实了第1点。
  3. 我试图找到负责 SHOW WARNINGS 的记录器,但找不到。我知道它是 not "org.hibernate.SQL"(更改日志级别无效)并且它是 not "org.hibernate" (该日志实际上并不存在)。
  4. 我打印出它们所有的当前日志级别并注意到它们都是 null(继承自 parent)。
  5. 我打印出层次结构并看到根记录器(名称“”)是唯一设置了日志级别的记录器,因此我设置了该日志级别。请注意,由于 Hibernate 日志通常设置为 "inherit",因此在配置 Hibernate 之前或之后执行此操作并不重要:如果在配置之前执行此操作,您将获得 no 日志记录,如果你在初始化期间仍然会看到它的输出,并且可能还会发出一些 SHOW WARNING,但这没什么大不了的。

这就是我得出上述结论的方式,这在我的解决方案中仍然存在以下草率:

  • 霰弹枪方法,不确定到底是哪个记录器负责,所以它们都被禁用了。
  • 因缺少 "org.hibernate" 而感到困惑。
  • 这仅在 JDK 日志记录正在使用时有效,这取决于上述假设。在您的 class 路径中放置另一个受支持的日志记录框架可能会导致 Hibernate select 一个不同的框架,从而使解决方案无效。
  • 我只尝试了 SEVERE,并验证它可以正常工作。不同的日志级别也可能有效,但我没有测试。

其他注意事项

我试图明确找出 Hibernate 有哪个记录器 auto-selected 但无法确定如何做到这一点(有人知道吗?)。我唯一的疯狂猜测是 ServiceRegistry 中的某些内容,但似乎没有与日志记录相关的 Service,或者至少我找不到。

一般来说,显式配置一个日志记录工具然后根据它的文档配置它更容易预测,例如,上面的解决方案仅仅通过添加另一个来中断JAR 到 class 路径。 但是,对于快速/one-off/无关紧要的项目,您只是最小化配置文件等,这似乎是删除 SHOW WARNING 的最简单方法命令。

hibernate 框架在默认情况下启用 MySQL 的 SHOW WARNING,每次查询都会触发,这会使查询数量翻倍至 MySQL,并且应用程序可能会出现性能问题。 hibernate 的 SHOW WARNING 附加日志记录可以建立在 -

org.hibernate.engine.jdbc.spi.SqlExceptionHelper#handleAndClearWarnings()

解决方案

让休眠选择一个合适的记录器。这可以通过添加来完成: -Dorg.jboss.logging.provider=slf4j-Dorg.jboss.logging.provider=log4j 作为 JVM 运行时参数。

对于 slf4j 记录器,您需要配置 logback.xml 文件。添加这个:

<logger name="org.hibernate.type" level="ERROR" /> 

对于 log4j 记录器,您需要将以下行添加到 log4j.properties :

log4j.logger.org.hibernate.type=ERROR

或者,您可以通过在 hibernate.properties 中添加 属性 来禁用 jdbc 警告文件(如果它与您的 application.properties 文件不在同一级别,则创建它):

hibernate.jdbc.log.warnings=false

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/appendices/Configurations.html