and*_*ndy 5 java logging hibernate
为了跟踪 hibernate SQL 语句的参数值,常见的 log4j 参数化如下所示:
<logger name="org.hibernate.SQL">
<level value="debug" />
</logger>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder">
<level value="trace" />
</logger>
Run Code Online (Sandbox Code Playgroud)
这会产生如下日志输出:
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]
Run Code Online (Sandbox Code Playgroud)
这对于分析应用程序路径在运行时如何执行非常有用。
问题是,这BasicBinder还记录了 LOB 参数值的整个字符串表示形式(例如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, ...
Run Code Online (Sandbox Code Playgroud)
整个 blob 的字符串表示形式被打印到日志文件中,这对我来说非常烦人。
有没有办法在 Hibernate 或 log4j 中抑制/缩短 LOB 值的日志输出,同时仍然显示其他语句参数的值?
是否可以在 log4j 中设置最大日志语句大小?
Hibernate 5.2.3已修复一个问题HHH-11097 ,这也应该可以解决您的问题:
在此提交中,BlobTypeDescriptor(和其他人)获得了以下内容的覆盖extractLoggableRepresentation:
@Override
public String extractLoggableRepresentation(Blob value) {
return value == null ? "null" : "BLOB{...}";
}
Run Code Online (Sandbox Code Playgroud)
默认实现(导致您的问题)现在被覆盖,如下所示:
@Override
public String extractLoggableRepresentation(T value) {
return (value == null) ? "null" : value.toString();
}
Run Code Online (Sandbox Code Playgroud)
这应该会从日志中删除那些巨大的行。
如果您使用的是最新版本的 hibernate,您可能会使用物化 blob/原始字节数组 ( byte[])。负责此操作的类型描述符是PrimitiveByteArrayTypeDescriptor,它疯狂地实现了extractLoggableRepresentation如下方法:
@Override
public String extractLoggableRepresentation(byte[] value) {
return (value == null) ? super.extractLoggableRepresentation( null ) : Arrays.toString( value );
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下我看到的唯一解决方案是
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);
}
Run Code Online (Sandbox Code Playgroud)
自定义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 + "]";
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1500 次 |
| 最近记录: |