Spring Boot AuditAware配置后数据库审计字段未更新问题求助
Spring Boot JPA审计字段未更新问题排查与解决
我是Spring Boot新手,想要添加审计支持,参考Spring Data JPA官方文档并经过多次尝试后,数据库中的审计字段(created、created_by、last_modified、last_modified_by)始终未更新。
现有代码配置
持久化配置
@Configuration @EnableTransactionManagement @EnableJpaRepositories("com.ncc.vrts") @EnableJpaAuditing(auditorAwareRef = "auditorAware") public class PersistenceConfiguration { @Bean AuditorAware<User> auditorAware() { return new AuditorAwareImpl(); } }
AuditorAwareImpl(调试确认可正确返回User对象)
@Component public class AuditorAwareImpl implements AuditorAware<User> { @Override public Optional<User> getCurrentAuditor() { return Optional.ofNullable(SecurityContextHolder.getContext()) .map(SecurityContext::getAuthentication) .filter(Authentication::isAuthenticated) .map(Authentication::getPrincipal) .map(User.class::cast); } }
AuditMetadata类
@Embeddable public class AuditMetadata { @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST}) @JoinColumn(name = "created_by") @CreatedBy private User createdBy; @Column(name = "created") @CreatedDate private Timestamp createdDate; @LastModifiedBy @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST}) @JoinColumn(name = "last_modified_by") private User lastModifiedBy; @Column(name = "last_modified") @LastModifiedDate private Timestamp lastModifiedDate; // 无setter和getter(添加后问题仍未解决) }
实体类
@Entity @Table(name = "trip_request") @SQLDelete(sql = "UPDATE trip_request SET deleted = true WHERE id=?") @FilterDef(name = "deletedRequestFilter", parameters = @ParamDef(name = "isDeleted", type = Boolean.class)) @Filter(name = "deletedRequestFilter", condition = "deleted = :isDeleted") @EntityListeners(AuditingEntityListener.class) public class Request { ... @Embedded private AuditMetadata auditingMetadata; ... // 无setter和getter }
控制器调用
// .save未被重写 requestRepository.save(request);
生成的SQL
Hibernate: select r1_0.id,r1_0.created_by,r1_0.created,r1_0.last_modified_by,r1_0.last_modified,r1_0.deleted,r1_0.expected_return_date_time,r1_0.last_updated,r1_0.note,r1_0.purpose,r1_0.request_date_time,r1_0.request_submitted,r1_0.status,r1_0.status_reviewed,r1_0.status_user_id,r1_0.user_id,r1_0.vehicle_id from trip_request r1_0 where r1_0.id=? Hibernate: update trip_request set created_by=?, created=?, last_modified_by=?, last_modified=?, deleted=?, expected_return_date_time=?, last_updated=?, note=?, purpose=?, request_date_time=?, request_submitted=?, status=?, status_reviewed=?, status_user_id=?, user_id=?, vehicle_id=? where id=?
数据库查询结果
select * from trip_request where id=8\G; *************************** 1. row *************************** id: 8 ... 除审计字段外其他字段均正常更新 created: NULL last_modified: NULL created_by: NULL last_modified_by: NULL
build.gradle配置
plugins { id 'java' id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' } group = 'com.ncc' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' repositories { mavenCentral() } dependencies { implementation 'com.okta.spring:okta-spring-boot-starter:3.0.3' implementation 'org.springframework.boot:spring-boot-starter-mail' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.2.0' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' implementation 'javax.servlet:javax.servlet-api:4.0.1' implementation 'io.hypersistence:hypersistence-utils-parent:3.2.0' implementation 'io.hypersistence:hypersistence-utils-hibernate-60:3.2.0' implementation 'io.openliberty.features:com.ibm.websphere.appserver.securityContext-1.0:23.0.0.2' runtimeOnly 'com.mysql:mysql-connector-j' developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
运行日志
2023-05-30T07:46:53.311-04:00 INFO 15224 --- [ restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2023-05-30T07:46:53.316-04:00 INFO 15224 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'entityManagerFactory' of type [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
问题排查与解决方案
1. 初始化嵌入式审计字段
嵌入式字段auditingMetadata默认是null,AuditingEntityListener无法对null对象的字段进行赋值。在Request实体中初始化该字段:
@Embedded private AuditMetadata auditingMetadata = new AuditMetadata();
2. 替换日期类型为Java 8+时间类
Spring Boot 3.x(对应JPA 3.x)对java.time包下的时间类型支持更完善,替换Timestamp为LocalDateTime:
@Embeddable public class AuditMetadata { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "created_by") @CreatedBy private User createdBy; @Column(name = "created") @CreatedDate private LocalDateTime createdDate; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "last_modified_by") @LastModifiedBy private User lastModifiedBy; @Column(name = "last_modified") @LastModifiedDate private LocalDateTime lastModifiedDate; // JPA需要无参构造器 public AuditMetadata() {} }
3. 避免AuditorAware Bean重复注册
AuditorAwareImpl已经通过@Component注册为Bean,无需在PersistenceConfiguration中手动创建,避免冲突:
@Configuration @EnableTransactionManagement @EnableJpaRepositories("com.ncc.vrts") @EnableJpaAuditing(auditorAwareRef = "auditorAwareImpl") // 使用组件默认名称(类名首字母小写) public class PersistenceConfiguration { // 移除auditorAware()方法 }
4. 确保关联User实体已持久化
@CreatedBy和@LastModifiedBy关联的User对象必须是数据库中已存在的实体(拥有有效主键),否则JPA无法插入关联外键值。确认AuditorAwareImpl返回的User是已持久化的实例。
5. 检查事务上下文
确保save操作在事务中执行,Spring Data JPA的save方法默认带事务,但如果控制器方法未被Spring管理或事务失效,可在控制器/Service方法上添加@Transactional注解。
内容的提问来源于stack exchange,提问作者user2182349
相关产品推荐
相关产品推荐

