@LastModifiedDate导致数据库额外更新,如何插入时设值且无额外更新?
解决Spring Data JPA @LastModifiedDate插入时额外更新的问题
这个问题确实挺头疼的——默认情况下用@LastModifiedDate时,新增实体总会多一条更新SQL;但设了modifyOnCreate=false后,又没法在插入时自动填充最后修改日期。我有两个实用的解决思路,亲测有效:
方法一:结合@PrePersist/@PreUpdate手动控制日期,关闭审计的创建时修改
这个方法的核心是用JPA的生命周期注解自己处理日期填充,同时让Spring Data的审计只在更新时生效,避免额外的更新操作。
步骤1:修改实体类,添加生命周期注解
@Entity public class YourEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 保留@LastModifiedDate注解,用于审计逻辑识别 @LastModifiedDate private LocalDateTime lastModifiedDate; // 插入前自动设置最后修改日期 @PrePersist public void prePersist() { LocalDateTime now = LocalDateTime.now(); this.lastModifiedDate = now; } // 更新前自动刷新最后修改日期 @PreUpdate public void preUpdate() { this.lastModifiedDate = LocalDateTime.now(); } // 其他字段和getter/setter }
步骤2:配置审计时关闭创建时修改
在你的JPA配置类里,设置modifyOnCreate=false:
@Configuration @EnableTransactionManagement @EnableJpaRepositories @EnableJpaAuditing(modifyOnCreate = false) public class JpaConfig { // 其他必要配置(比如AuditorAware如果用到的话) }
这样一来,插入实体时@PrePersist会把日期写入INSERT语句,不会触发额外的UPDATE;更新实体时@PreUpdate会刷新日期,同时审计逻辑也会正常工作。
方法二:数据库层面设置默认值,剥离Spring审计的日期填充
如果项目允许依赖数据库的特性,可以直接在字段上设置默认值和自动更新,完全不用Spring Data的日期审计:
@Entity public class YourEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP") private LocalDateTime lastModifiedDate; // 其他字段和getter/setter }
这种方式下,创建和更新时的日期都由数据库自动维护,Spring Data只负责读写,自然不会有额外的更新SQL。不过缺点是日期的生成逻辑和代码解耦了,需要团队统一认知。
为什么默认会有额外更新?
简单说:当modifyOnCreate=true(默认值)时,Spring Data JPA的审计逻辑会先执行INSERT语句,然后再触发一次UPDATE来设置@LastModifiedDate的值,所以会产生两条SQL。而modifyOnCreate=false会跳过创建时的审计更新,也就不会填充日期了——咱们上面的方法就是绕开这个矛盾点,让日期在INSERT阶段就被正确设置。
内容的提问来源于stack exchange,提问作者Pavel F
相关产品推荐
相关产品推荐

