Значения трассировки гибернации параметров оператора, кроме BLOB-объектов - PullRequest
0 голосов
/ 10 января 2019

Чтобы отследить значения параметров операторов SQL Hibernate, общая параметризация log4j выглядит следующим образом:

<logger name="org.hibernate.SQL">
  <level value="debug" />
</logger>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder">
  <level value="trace" />
</logger>

Это приводит к выводу журнала следующим образом:

2019-01-10 00:10:29,349 [main] DEBUG  SqlStatementLogger.logStatement(SqlStatementLogger.java:92) - select land0_.fk_land as fk_land1_24_0_ from land land0_ where land0_.fk_land=?
2019-01-10 00:10:29,349 [main] TRACE  BasicBinder.bind(BasicBinder.java:65) - binding parameter [1] as [BIGINT] - [27]

Это очень полезно для анализа того, как путь приложения был выполнен во время выполнения.

Проблема в том, что BasicBinder также регистрирует целое строковое представление значений параметров больших объектов (например, byte[]), что очень бесполезно:

2019-01-07 13:28:45,466 [wwsservices-catalina-exec-10] TRACE   org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [2] as [BLOB] - [[37, 80, 68, 70, 45, 49, 46, 52, ...

Строковое представление всего большого двоичного объекта печатается в файле журнала, что меня очень раздражает.

Есть ли способ подавить / сократить вывод журнала значений LOB в Hibernate или log4j при отображении значений других параметров оператора?

Есть ли возможность установить максимальный размер оператора журнала в log4j?

1 Ответ

0 голосов
/ 26 марта 2019

Возникла проблема HHH-11097 , исправленная для Hibernate 5.2.3, которая также должна решить вашу проблему:

В при этом коммите , BlobTypeDescriptor (и другие) получают переопределение для extractLoggableRepresentation:

@Override
public String extractLoggableRepresentation(Blob value) {
    return value == null ? "null" : "BLOB{...}";
}

Реализация по умолчанию (вызывающая вашу проблему) теперь переопределена, выглядит следующим образом:

@Override
public String extractLoggableRepresentation(T value) {
    return (value == null) ? "null" : value.toString();
}

Это должно удалить эти гигантские линии из вашего журнала.

Если вы используете последнюю версию hibernate, вы, скорее всего, используете материализованные массивы больших двоичных объектов / примитивные байты (byte[]). Дескриптор типа, отвечающий за это: PrimitiveByteArrayTypeDescriptor , который безумно реализует метод extractLoggableRepresentation следующим образом:

@Override
public String extractLoggableRepresentation(byte[] value) {
    return (value == null) ? super.extractLoggableRepresentation( null ) : Arrays.toString( value );
}

Единственные решения, которые я вижу в этом случае, это

  • Сообщить об ошибке
  • Предотвращение использования материализованных капель.
  • Используйте обходной путь, внедрив пользовательский UserType:

Пользовательский UserType должен реализовать nullSafeSet и передать пользовательский JavaTypeDescriptor в механизм связывания, который выполняет привязку и ведение журнала:

@Override
public void nullSafeSet(PreparedStatement st, Object value, int index,
        final SharedSessionContractImplementor session) throws HibernateException, SQLException {

    // Simply do what 
    // org.hibernate.type.AbstractStandardBasicType.nullSafeSet(PreparedStatement, Object, int, WrapperOptions)
    // does, but using a custom descriptor.

    session.remapSqlTypeDescriptor(MaterializedBlobType.INSTANCE.getSqlTypeDescriptor())
            .getBinder(CustomPrimitiveByteArrayTypeDescriptor.INSTANCE)
            .bind(st, (byte[]) value, index, session);
}

Пользовательский JavaTypeDescriptor просто расширяет PrimitiveByteArrayTypeDescriptor и переопределяет проблемный extractLoggableRepresentation метод:

public class CustomPrimitiveByteArrayTypeDescriptor extends PrimitiveByteArrayTypeDescriptor {
    public static final CustomPrimitiveByteArrayTypeDescriptor INSTANCE = new CustomPrimitiveByteArrayTypeDescriptor();

    @Override
    public String extractLoggableRepresentation(byte[] value) {
        if (null == value) {
            return super.extractLoggableRepresentation(value);
        } else {
            return "byte[" + value.length + "]";
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...