如何从 Hibernate 禁用 SHOW WARNINGS?

Jas*_*n C 5 java mysql hibernate hibernate-4.x

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

在此处输入图片说明

我四处搜索,这是一个非常常见的问题(例如),显然可以通过将日志级别增加到 ERROR来解决(并且该解决方案至少从 4.3.6 起已确认实施)。

问题是,我实际上不知道如何做到这一点。我对 Hibernate 的了解是使用它所需的最低限度的知识。之前链接的帖子通过编辑 Logback 设置解决了这个问题,logback.xml但我没有使用 Logback。我正在使用所有默认设置:

  • 显然它使用JBoss Logging 作为其核心。
  • 我的类路径中没有任何其他日志记录依赖项(例如 slf4j.jar),所以我绝对不会使用它们。日志消息只是被写出到System.err.

所以我实际上不确定如何做到这一点。这是我的配置文件:

<?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>
Run Code Online (Sandbox Code Playgroud)

以下是构建路径中的依赖项;有 Jettison 和 Joda,MySQL 驱动程序,然后是 Hibernaterequired依赖目录中的所有内容,仅此而已:

在此处输入图片说明

SHOW WARNINGS在这种(默认设置)情况下,如何提高日志级别或以其他方式禁用?提到了“感兴趣的日志类别”,但我不确定这些与配置文件有什么关系。此页面在“日志记录”部分之外没有记录任何与日志相关的属性,其中提到了 SLF4J,但显然我没有使用 SLF4J(我怎么会这样,因为它不在我的类路径中)。

Jas*_*n C 1

好的。我明白了这一点,并在这个过程中学到了很多东西。


长话短说:

在以下假设下...

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

... Hibernate 将通过 JBoss Logging 自动选择 JDK 日志记录,并且java.util.logging可以使用该工具来控制日志级别。因此,在根记录器级别将所有 JDK 日志的日志级别设置为SEVERE, (无论您在 Hibernate 初始化之前还是之后执行此操作都没有关系,请参见下文)可成功停止命令SHOW WARNING

LogManager.getLogManager().getLogger("").setLevel(Level.SEVERE);
Run Code Online (Sandbox Code Playgroud)

然而,这是一种霰弹枪方法,它为所有Logger级别设置为(从父级继承)的注册者设置日志级别null


JDK 日志记录说明

我通过以下方式找到了上述解决方案:

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

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

  • Shotgun 方法,不确定记录器到底负责什么,所以它们都被禁用。
  • 由于缺少“org.hibernate”而感到困惑。
  • 这仅在使用 JDK 日志记录时才有效,这依赖于上述假设。将另一个受支持的日志框架放入类路径中可能会导致 Hibernate 选择不同的框架,从而使解决方案无效。
  • 我只是尝试过SEVERE,并验证它是否有效。不同的日志级别也可能有效,但我没有测试。

其他注意事项

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

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