hibernate - 从我的 SystemOut.log 文件中重定向 hibernate 错误

标签 hibernate configuration log4j appender redirect

我的 hibernate 日志配置有一点问题。
在我们的应用程序中,我们有两个线程同时尝试在数据库表的每一行上加锁。
有时,其中一个线程会尝试锁定已经锁定的行。抛出此错误:

[2/24/12 15:00:34:492 CET] 0000003a JDBCException W org.hibernate.util.JDBCExceptionReporter logExceptions SQL Error: 54, SQLState: 61000
[2/24/12 15:00:34:496 CET] 0000003a JDBCException E org.hibernate.util.JDBCExceptionReporter logExceptions ORA-00054: resource busy and acquire with NOWAIT specified

这些行放在 SystemOut.log 文件中。我正在尝试将它们放在另一个文件中。所以在我的 Log4j 配置文件中,我创建了一个新的 appender,如下所示:
<appender name="JDBCExceptionReporter" class="org.apache.log4j.RollingFileAppender">
    <param name="Encoding" value="UTF-8"/>
    <param name="File" value="JDBCExceptionReporter.log"/>
    <param name="MaxFileSize" value="50000KB"/>
    <param name="MaxBackupIndex" value="5"/>
    <param name="BufferedIO" value="false"/>
    <param name="ImmediateFlush" value="true"/>
    <param name="Append" value="true"/>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d, %-5p, %X{ORG_NAME}, %X{USER_NAME}, %c - %m%n"/>
        <!-- Use pattern below if it is required to view the log files   -->
        <!-- using LogFactor5-->
        <!--<param name="ConversionPattern" value="[slf5s.start] %d[slf5s.DATE]
            %-5p[slf5s.PRIORITY] %X{ORG_NAME} %X{USER_NAME}
            [slf5s.NDC] %c[slf5s.CATEGORY] - %m[slf5s.MESSAGE] %n"-->
    </layout>
</appender>

最后,我在根元素之前添加了这些记录器:
<logger name="org.hibernate" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>
<logger name="org.hibernate.type" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>
<logger name="org.hibernate.tool.hbm2ddl" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>
<logger name="org.hibernate.pretty" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>
<logger name="org.hibernate.cache" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>
<logger name="org.hibernate.transaction" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>
<logger name="org.hibernate.jdbc" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>
<logger name="org.hibernate.hql.ast.AST" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>
<logger name="org.hibernate.secure" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>
<logger name="org.hibernate.SQL" additivity="false">
    <level value="ALL"/>
    <appender-ref ref="JDBCExceptionReporter"/>
</logger>

此配置不起作用,这两行始终记录在 SystemOut.log 中,而不是我的 JDBCExceptionReporter.log 中。
有人知道我的问题吗?
感谢您的帮助。

最佳答案

Hibernate 不直接使用 Log4J。这就是您的消息落入 WebSphere SystemOut.log 文件的原因。

直到 3.2 版本,hibernate 使用 Jakarta Commons Logging 作为日志外观。从 3.3 及更高版本开始,它切换到 SLF4J(Java 的简单日志记录外观)。作为 jakarta commons logging (JCL),SLF4J 只是一个门面,通常绑定(bind)到其他 Logging Framework,例如 Java Logging,或者在本例中是 Log4J 本身。

我了解您的应用程序已经使用 Log4J。我还假设您使用的是 Hibernate 3.3 或更新版本。

首先是为您的项目添加 SLF4J 支持。你可以通过添加这些依赖项来做到这一点(使用 Ivy、Maven 或任何你想要的):

slf4j-api.jar (核心 SLF4J 包)

slf4j-log4j12.jar (将 SLF4J 绑定(bind)到 Log4J)

这样,当 Hibernate 记录一些消息时,SLF4J 将捕获它并将其路由到 Log4J。

现在,当涉及到您自己的应用程序代码时,您有两种方法。

1:让你的类直接与 Log4J 类交互(即 Logger 和 LoggerFactory)

这样,您可以让您的类直接引用 Log4J Logger,如下所示:

Logger  logger = Logger.getLogger("com.foo"); // from package org.apache.log4j

因此,简而言之,Hibernate 将使用 SLF4J -> Log4J,而您将直接使用 Log4J

2:第二种方法是让您的代码也使用 SLF4J。这并不是什么大的变化,因为您可能只需要在每个生成日志消息的类中更改一行代码:
Logger  logger = LoggerFactory.getLogger("com.foo"); // from package org.slf4j

如果您使用的是旧版本的 Hibernate(3.2 或更早版本),则必须欺骗它不要使用 Jakarta Commons Logging。首先,您必须从您的依赖项中清除 commons-logging JAR 文件(手动或排除,如果您使用任何依赖项管理器)。然后,您必须将 Commons-logging 的 SLF4J 端口添加到您的类路径:

添加 jcl-over-slf4j-x.y.z.jar (x.y.z 是它的版本。例如,我使用 jcl-over-slf4j-1.6.1.jar )。

这个 jar 具有旧 commons-logging.jar 的确切类和包,因此实际上有效地欺骗了所有依赖于 commons-logging 的应用程序登录到 SLF4J。

关于hibernate - 从我的 SystemOut.log 文件中重定向 hibernate 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9432255/

相关文章:

java - 如何从代码而不是从我的 application-dev.yml、application-prod.yml 初始化属性

git - 如何在 git 设置之间同步配置?

java - Log4j 不发送日志到 linux SYSLOG

java - 是否可以将 JBOSS AS 7 配置为使用 log4j 而不是其自己的日志框架?

mysql - SQL Error : 1054, SQLState : 42S22 , Spring Boot jpa 应用程序中 'NaN' 中的未知列 'field list'

mysql - 如何确定 c3p0 max_statements

java - 我的实体加载速度超慢有什么问题?

java - 如何创建一个允许 NULL 值与 Hibernate 注释的唯一约束?

python - config.py 模块的配置文件中的函数 eval

java - 如何更改所有 Log4J 1.x 记录器的级别?