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

时间:2012-02-24 14:21:26

标签: hibernate configuration log4j appender redirect

我的hibernate日志记录配置有点问题。     在我们的应用程序中,我们有两个线程试图同时在Database表的每一行上放置一个锁。     有时,其中一个线程试图锁定已经锁定的行。抛出此错误:

[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中。 有没有人能解决我的问题? 谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

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

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

我知道你的应用程序已经使用了Log4J。我还假设您正在使用Hibernate 3.3或更新版本。

首先要为您的项目添加SLF4J支持。你可以通过添加这些依赖项(使用Ivy,Maven或者你想要的)来实现:

slf4j-api.jar (核心SLF4J包)

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

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

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

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

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

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

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

2:第二种方法是让您的代码也使用SLF4J。这不是一个很大的变化,因为您可能只需要在每个产生日志消息的类中更改一行代码:

Logger  logger = LoggerFactory.getLogger("com.foo"); // from package org.slf4j

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

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

这个jar具有旧的commons-logging.jar的确切类和包,因此实际上有效地欺骗所有与commons-logging相关的应用程序以记录到SLF4J。