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