перенаправление ошибки Hibernate из моего файла SystemOut.log - PullRequest
4 голосов
/ 24 февраля 2012

У меня небольшая проблема с конфигурацией ведения журнала в спящем режиме.В нашем приложении у нас есть два потока, пытающихся одновременно блокировать каждую строку таблицы базы данных.иногда один из этих потоков пытается заблокировать уже заблокированную строку.Выдается эта ошибка:

[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 Ответ

1 голос
/ 14 июня 2012

Hibernate не использует Log4J напрямую. Вот почему ваши сообщения попадают в файл WebSphere SystemOut.log.

До версии 3.2 hibernate использовал Jakarta Commons Logging в качестве фасада. С версии 3.3 и выше она переключилась на SLF4J (Simple Logging Facade для Java). Как и в случае с журналом общего пользования в Джакарте (JCL), SLF4J - это просто фасад, часто привязываемый к другим структурам ведения журнала, таким как ведение журнала Java или, в данном случае, к самому Log4J.

Я понимаю, что ваше приложение уже использует Log4J. Я также предполагаю, что вы используете Hibernate 3.3 или более новую версию.

Прежде всего, добавьте поддержку SLF4J в ваш проект. Вы делаете это, добавляя эти зависимости (с Ivy, Maven или как хотите):

slf4j-api.jar (пакеты Core 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 -> Log4J, а вы будете использовать непосредственно Log4J

2: Второй подход заключается в том, чтобы ваш код также использовал SLF4J. Это не такое большое изменение, так как вам, вероятно, придется изменить только одну строку кода в каждом из ваших классов, которая создает сообщения журнала:

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

Если вы используете более старую версию Hibernate (3.2 или более раннюю), вам придется обмануть ее, чтобы не использовать Jakarta Commons Logging. Во-первых, вам нужно будет удалить файлы JAR, регистрирующие достояние, из ваших зависимостей (вручную или с исключением, если вы используете какой-либо менеджер зависимостей). Затем вам нужно добавить порт общего входа SLF4J в ваш classpath:

add jcl-over-slf4j-xyzjar (xyz - его версия. Я использую jcl-over-slf4j-1.6.1.jar , например).

Этот jar имеет точные классы и пакеты старого commons-logging.jar, таким образом, эффективно обманывая все зависимые от commons-logging приложения для входа в SLF4J.

...