You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Log4j JPAAppender Blob垃圾数据问题改造后报错求解决方案

我之前也碰到过Log4j JPAAppender存大体积Blob垃圾数据的坑,调试了好一阵才搞定,结合你现在遇到的报错问题,给你详细的解决方案:

1. 解决「Entity class does not extend AbstractLogEventWrapperEntity」报错

这个报错的核心是你重写的JPAAppender类里,还保留了原生Log4j的校验逻辑——它要求日志实体类必须继承AbstractLogEventWrapperEntity父类。你有两种解决方式:

方式一:让自定义实体类继承父类

直接修改你的com.log4jtest.demo.logger.JpaLogEntity,让它继承org.apache.logging.log4j.core.appender.db.jpa.AbstractLogEventWrapperEntity:

public class JpaLogEntity extends AbstractLogEventWrapperEntity {
    // 你的实体字段和自定义逻辑
}

这样就能绕过校验逻辑。同时别忘了保持你之前对wrappedEvent字段的修改:确保它带有@Transient注解,避免被EntityManager持久化(这也是解决Blob垃圾数据的关键)。

方式二:移除校验逻辑,完全自定义实体类

如果你不想依赖Log4j的父类,可以修改你重写的JPAAppender相关类(比如JpaDatabaseManager或者JpaAppender的初始化代码),把这段校验代码删掉:

// 找到类似这样的代码并删除
if (!AbstractLogEventWrapperEntity.class.isAssignableFrom(entityClass)) {
    throw new IllegalArgumentException("Entity class [" + entityClass.getName() + "] does not extend AbstractLogEventWrapperEntity");
}

之后你可以完全自定义实体类,自己映射LogEvent的各个字段(比如日志级别、消息内容、时间戳等)为普通的Java类型(String、Long、Date等),不需要持有LogEvent对象,从根源避免序列化产生Blob垃圾。

2. 彻底解决Blob垃圾数据的可行方案

结合你已经修改wrappedEvent的思路,这里给你更完善的实现:

  • 核心问题:原生AbstractLogEventWrapperEntity的wrappedEvent虽然加了@Transient,但部分JPA提供者(比如Hibernate)的自动探测机制还是会尝试序列化这个对象,导致生成大体积Blob垃圾。
  • 具体修改:
    • 给wrappedEvent字段加上双重忽略注解:除了JPA的@Transient,再加上Hibernate专属的@org.hibernate.annotations.Transient(如果用Hibernate的话),或者@JsonIgnore(如果有JSON序列化场景),彻底阻止序列化。
    • 如果你选择完全自定义实体类,不要直接持有LogEvent对象,而是把LogEvent里的必要字段拆解成简单类型持久化。比如把logEvent.getMessage()存为String,logEvent.getTimeMillis()存为Long,这样完全避免复杂对象的序列化问题。
    • 检查JPA配置,关闭可能触发不必要序列化的选项,比如Hibernate的hibernate.enable_lazy_load_no_trans这类配置,防止框架自动序列化未标记的字段。

内容的提问来源于stack exchange,提问作者Domingo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:56:42