如何从Hibernate中禁用SHOW WARNINGS?

时间:2017-05-26 23:47:35

标签: java mysql hibernate hibernate-4.x

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

enter image description here

我四处搜索,这是一个非常常见的问题(for example),显然可以通过increasing the log level to ERROR来解决(问题解决方案是confirmed implemented,因为至少4.3.6)

问题是,我实际上并不知道如何做到这一点。我对Hibernate的了解是使用Hibernate所必需的最低限度。之前链接的帖子通过编辑logback.xml中的Logback设置解决了它,但我没有使用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>

以下是构建路径中的依赖项;那里有Jettison和Joda,MySQL驱动程序,然后是Hibernate的required依赖目录中的所有内容,而不是其他内容:

  

enter image description here

如何在此(默认设置)情况下提高日志级别或以其他方式禁用SHOW WARNINGSThis提及&#34;记录感兴趣的类别&#34;但我不确定这些与配置文件有何关系。 This page没有在&#34;记录&#34;之外记录任何与日志相关的属性。提到SLF4J的部分,但显然我没有使用SLF4J(我怎么可能,因为它不在我的类路径中)。

3 个答案:

答案 0 :(得分:2)

hibernate框架默认启用MySQL的SHOW WARNING,每次查询都会触发,这会使MySQL的查询数量翻倍,应用程序可以实现性能问题。可以通过 -

建立休眠的SHOW WARNING的额外日志记录
org.hibernate.engine.jdbc.spi.SqlExceptionHelper#handleAndClearWarnings()

<强>解决方案

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

对于slf4j logger,您需要配置logback.xml文件。加上这个:

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

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

log4j.logger.org.hibernate.type=ERROR

答案 1 :(得分:0)

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

TL; DR:

根据以下假设......

  • 未明确配置任何日志记录选项。
  • 类路径中唯一与日志相关的JAR是jboss日志记录(即没有slf4j,log4j等)。

... Hibernate将automatically select JDK logging via JBoss Loggingjava.util.logging工具可用于控制日志级别。因此,在根记录器级别将所有JDK日志的日志级别设置为SEVERE(如果在Hibernate初始化之前或之后执行此操作并不重要,请参见下文)成功停止SHOW WARNING命令:

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

但是,这是一种霰弹枪方法,用于设置所有注册Logger的日志级别,这些级别的级别设置为null(从父级继承)。

JDK记录笔记

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

  1. 阅读the logging doc几次直到它沉入,并将该信息与我的类路径中的内容相关联,证据表明正在使用JDK日志记录。
  2. 查看来自LogManager#getLoggerNames()的记录器名称列表。 Hibernate有很多,这个证实了第1点。
  3. 我试图找到负责SHOW WARNINGS的记录器,但却没有。我知道它是不是&#34; org.hibernate.SQL&#34; (更改该日志级别没有任何效果)并且不是&#34; org.hibernate&#34; (该日志实际上并不存在)。
  4. 我打印出所有这些日志的当前日志级别,并注意到它们都是null(从父级继承)。
  5. 我打印出层次结构,看到根记录器(名称&#34;&#34;)是唯一一个设置了日志级别的记录器,因此我设置了该日志级别。请注意,由于Hibernate日志通常设置为&#34;继承&#34;,如果您在配置Hibernate之前或之后执行此操作并不重要:如果您在使用之前执行此操作>没有日志记录,如果你在初始化过程中仍然看到它的输出并且可能还会发出几个SHOW WARNING之后再进行日志记录,但这不是什么大问题
  6. 这就是我如何达到上述目标,这仍然在我的解决方案中留下了以下的邋:::

    • Shotgun方法,不确定记录器究竟负责什么,所以他们都被禁用了。
    • 因缺乏&#34; org.hibernate&#34;而感到困惑。
    • 仅在使用JDK日志记录时才有效,这依赖于上述假设。在类路径中放置另一个受支持的日志记录框架可能会导致Hibernate选择不同的框架,从而使解决方案无效。
    • 我只试过SEVERE,并确认它正常运行。不同的日志级别也可以,但我没有测试。

    其他注释

    我试图明确找出哪个记录​​器Hibernate已经自动选择但无法确定如何做到(任何人都知道?)。我唯一猜测的是ServiceRegistry中的内容,但似乎没有与日志相关的Service,或者至少我找不到。{3}}

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

答案 2 :(得分:0)

或者,您也可以通过在 hibernate.properties 文件中添加属性来禁用jdb​​c警告(如果该文件与您的 application.properties 文件):

hibernate.jdbc.log.warnings=false

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