如何禁用 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。我正在使用所有默认设置:
- 显然它的核心使用 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
依赖目录中的所有内容,没有别的:
在这种(默认设置)情况下,如何提高日志级别或禁用 [=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 记录笔记
我通过以下方式得出上述解决方案:
- 阅读 the logging doc 几次,直到它沉没,并将该信息与我的 class 路径中的内容相关联,证据表明 JDK 日志记录正在使用中。
- 查看了
LogManager#getLoggerNames()
中的记录器名称列表。来自Hibernate的有不少,这证实了第1点。
- 我试图找到负责
SHOW WARNINGS
的记录器,但找不到。我知道它是 not "org.hibernate.SQL"(更改日志级别无效)并且它是 not "org.hibernate" (该日志实际上并不存在)。
- 我打印出它们所有的当前日志级别并注意到它们都是
null
(继承自 parent)。
- 我打印出层次结构并看到根记录器(名称“”)是唯一设置了日志级别的记录器,因此我设置了该日志级别。请注意,由于 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
在 MySQL 中使用 Hibernate (4.3.8),我注意到 activity 日志中有一堆 SHOW WARNINGS
语句占用了相当大的带宽:
我四处搜索了一下,这是一个很常见的问题(for example) that can apparently be resolved by
问题是,我实际上不知道该怎么做。我对 Hibernate 的了解只是使用它所必需的最低限度。之前链接的 post 通过编辑 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
依赖目录中的所有内容,没有别的:
在这种(默认设置)情况下,如何提高日志级别或禁用 [=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 记录笔记
我通过以下方式得出上述解决方案:
- 阅读 the logging doc 几次,直到它沉没,并将该信息与我的 class 路径中的内容相关联,证据表明 JDK 日志记录正在使用中。
- 查看了
LogManager#getLoggerNames()
中的记录器名称列表。来自Hibernate的有不少,这证实了第1点。 - 我试图找到负责
SHOW WARNINGS
的记录器,但找不到。我知道它是 not "org.hibernate.SQL"(更改日志级别无效)并且它是 not "org.hibernate" (该日志实际上并不存在)。 - 我打印出它们所有的当前日志级别并注意到它们都是
null
(继承自 parent)。 - 我打印出层次结构并看到根记录器(名称“”)是唯一设置了日志级别的记录器,因此我设置了该日志级别。请注意,由于 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