Как обрабатывать null при установке даты в log4j2 jdbcappender?

Когда я устанавливаю нулевое значение в столбце даты, я получаю значение «1900-01-01 00: 00: 00.000» в моей таблице, и я ожидаю NULL в этом столбце. Поскольку это правильно обрабатывается в jdbc, если я поставлю вот так

preparedStatement.setBindParam(Types.TIMESTAMP, 12, startdate);

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">

    <CustomLevels>
        <CustomLevel name="TESTLOG" intLevel="552" />
    </CustomLevels>

    <Appenders>

        <JDBC name="myAppender" tableName="MYTABLE">
            <DataSource jndiName="java:MyDataSource" />
            <Column name="ID" pattern="%X{ID}" isUnicode="false"/>
            <Column name="startdate" pattern="%X{startdate}" isUnicode="false"/>
            <Column name="enddate" pattern="%X{enddate}" isUnicode="false"/>
        </JDBC>

    </Appenders>

    <Loggers>
        <Root level="trace"  includeLocation="false">
            <AppenderRef ref="myAppender" level="TESTLOG" />
        </Root>
    </Loggers>

</Configuration>

Тип данных для столбцов startdate и enddate: datetime.

ThreadContext.put("startdate", startdate != null ? startdate.toString() : null);
ThreadContext.put("enddate", a_reportEndDate != null ? enddate.toString() : null);
final Logger LOGGER = LogManager.getLogger();
LOGGER.log(Level.forName("TESTLOG", 552), "");

То же самое и для String с нулевым значением.


person happy    schedule 30.11.2017    source источник
comment
Может быть, ваша таблица была создана со значениями по умолчанию для столбцов с отметками времени?   -  person Ivan    schedule 04.12.2017


Ответы (1)


Вставка нуля

Я не думаю, что можно поместить null в любой столбец любого типа, используя JDBCAppender с подобными шаблонами.

Эта ветка появилась пару лет назад, за ней последовала эта проблема Jira < / а>. Кажется, ничто из этого не привлекло внимания.

Краткая версия заключается в том, что StringBuilder используется между шаблоном и подготовленным оператором, и поэтому INSERT всегда получает ненулевую строку, даже если (в вашем примере) null является значением в ThreadContext. Таким образом, можно вставить пустую строку или строку "null", но не представляется возможным вставить значение null.

1 января 1900 г.

Когда я запускаю ваш пример для базы данных MySQL, вставка не выполняется сразу, потому что MySQL не знает, как построить DATETIME из пустой строки.

Я предполагаю, что вы используете SQL Server, который с радостью превратит пустую строку в 1900-01-01 00:00:00.000, потому что конечно это то, что вы имели в виду.

Независимо от того, какую базу данных вы используете, JDBCAppender заполнит оператор INSERT ненулевыми строками. То, что происходит оттуда, будет варьироваться от БД к БД.

Почему?

Сначала может показаться странным, что фреймворк меняет ваше значение (null) на другое значение (пустая строка). Однако, по сути, ведение журнала касается строк текста.

Да, есть приложение, которое записывает эти строки в базу данных. И да, ваша база данных может, в свою очередь, преобразовать эти строки в типы вроде DATETIME или INTEGER. Но для любого конкретного аппендера на самом деле все сводится к манипулированию и выводу строк.

Возможный обходной путь

Если вы действительно хотите добавить null в базу данных с помощью JDBCAppender, вы можете написать триггер.

Последнее наблюдение

Не уверен, что это поможет, но я могу представить все свои выводы:

Использование ColumnMapping вместо Column в конфигурации log4j позволяет указать имя класса. Наличие (или отсутствие) и значение этого имени класса изменяет значение, которое вставляется в базу данных. Например, используя SQL Server Express 2014:

<ColumnMapping name="startdate" pattern="%X{startdate}" type="java.sql.Timestamp"/>

Заставит регистрировать текущую дату и время, когда startdate имеет значение null вместо 1900-01-01. Использование java.sql.Date вместо этого приведет к регистрации текущей даты без времени.

person Mike Patrick    schedule 06.12.2017
comment
Поскольку я использую java 6, а ColumnMapping не поддерживается в log4j-core-2.3.jar - person happy; 06.12.2017