Spring Boot 1.4升级至2.1.x后@Embedded审计功能失效问题求助
适配Spring Boot 2.1.x版本的解决方案
失效根因
Spring Boot 2.1.x 对应升级的 Spring Data JPA 2.1.x、Hibernate 5.3+ 版本有两个核心变更导致原有逻辑失效:
- JPA 实体监听器默认由 Hibernate 直接实例化,不再默认关联 Spring 容器,若代码中用到的
ContextHolder、BeanHolder属于 Spring 管理的组件,会出现取值失败导致填充逻辑中断。 - Hibernate 对
@Embeddable字段的空值处理策略调整:如果@Embedded字段初始为null,部分场景下手动 set 新的 Embeddable 实例后,Hibernate 不会将其识别为待持久化的有效字段。
适配方案(完全保留原有@Embedded实现逻辑)
步骤1:让Spring接管自定义实体监听器的实例化
给PersistableEntityListener类添加Spring管理注解:
import org.springframework.beans.factory.annotation.Configurable; import org.springframework.stereotype.Component; @Component @Configurable public class PersistableEntityListener { // 原有代码完全保留即可 }
同时在Spring Boot启动类/配置类上添加@EnableSpringConfigured注解,开启AspectJ对非Spring直接实例化Bean的织入支持,保证Hibernate创建的监听器实例也能正常获取Spring容器中的组件。
如果项目未引入AspectJ依赖,补充对应依赖即可:
<!-- Maven 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency>
步骤2:初始化@Embedded字段避免空值识别问题
在实体类中直接初始化@Embedded修饰的审计字段,避免Hibernate忽略空字段的更新:
@Entity @Table(name = "TRACKABLE_ITEM") @Inheritance(strategy = InheritanceType.JOINED) public class ETrackableItem extends AbstractIdTenantPersistable implements EAuditable.Create, EAuditable.Update { @Embedded private ECreateInfo createInfo = new ECreateInfo(); @Embedded private EUpdateInfo updateInfo = new EUpdateInfo(); // 原有get、set方法无需修改 }
原有监听器的逻辑可以完全保留,也可以优化为直接修改现有实例的属性而非创建新实例,兼容性更好:
@PrePersist public void prePersist(AbstractPersistable e) { if (e instanceof EAuditable.Create){ EAuditable.Create create = (EAuditable.Create) e; ECreateInfo info = create.getCreateInfo(); info.setCreatedOn(ZonedDateTime.now(ZoneId.of("UTC"))); info.setCreatedBy(getUserName()); } // 其他原有逻辑保持不变 }
步骤3:可选兼容配置(如果上述调整后仍不生效)
在application.yml中添加配置,关闭Hibernate字节码优化对反射调用的影响:
spring: jpa: properties: hibernate: bytecode: use_reflection_optimizer: false
内容的提问来源于stack exchange,提问作者satyabrata mohapatra
相关产品推荐
相关产品推荐

