4

休止状態のログ設定に少し問題があります。このアプリケーションでは、データベース テーブルの各行を同時にロックしようとする 2 つのスレッドがあります。場合によっては、これらのスレッドの 1 つが、既にロックされている行をロックしようとします。このエラーがスローされます:

[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 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>

この構成は機能せず、2 行は常に SystemOut.log に記録され、JDBCExceptionReporter.log には記録されません。誰かが私の問題に対する答えを持っていますか? ご協力ありがとうございました。

4

1 に答える 1

1

HibernateはLog4Jを直接使用しません。これが、メッセージがWebSphereSystemOut.logファイルに分類される理由です。

バージョン3.2まで、hibernateはJakartaCommonsLoggingをロギングファサードとして使用していました。バージョン3.3以降では、SLF4J(Simple Logging Facade for Java)に切り替わりました。jakarta commons logging(JCL)として、SLF4Jは単なるファサードであり、多くの場合、Javaロギング、この場合はLog4J自体などの他のロギングフレームワークにバインドされます。

アプリケーションがすでにLog4Jを使用していることを理解しています。また、Hibernate3.3以降のバージョンを使用していることも前提としています。

まず、プロジェクトにSLF4Jサポートを追加します。これを行うには、次の依存関係を追加します(Ivy、Maven、または任意の方法で)。

slf4j-api.jar(コアSLF4Jパッケージ)

slf4j-log4j12.jar(SLF4JをLog4Jにバインドします)

このように、Hibernateがメッセージをログに記録すると、SLF4Jはそれをキャプチャし、Log4Jにルーティングします。

さて、あなた自身のアプリコードに関しては、2つのアプローチがあります。

1:クラスをLog4Jクラス(つまり、LoggerおよびLoggerFactory)と直接対話させます

このようにして、次のように、クラスがLog4JLoggerを直接参照するようにします。

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

つまり、HibernateはSLF4J-> Log4Jを使用し、Log4Jを直接使用します。

2:2番目のアプローチは、コードでSLF4Jも使用することです。これはそれほど大きな変更ではありません。ログメッセージを生成する各クラスのコードを1行だけ変更する必要があるからです。

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

古いバージョンのHibernate(3.2以前)を使用している場合は、JakartaCommonsLoggingを使用しないように騙す必要があります。まず、commons-logging JARファイルを依存関係から削除する必要があります(手動で、または依存関係マネージャーを使用している場合は除外して)。次に、commons-loggingのSLF4Jポートをクラスパスに追加する必要があります。

jcl-over-slf4j-xyzjarを追加します(xyzはそのバージョンです。たとえば、 jcl-over-slf4j-1.6.1.jarを使用します)。

このjarには、古いcommons-logging.jarの正確なクラスとパッケージが含まれているため、実際には、すべてのcommons-logging依存アプリケーションをだましてSLF4Jにログを記録します。

于 2012-06-13T20:51:33.357 に答える