在 Spring Data JDBC 中绕过 @CreatedDate 和 @LastModifiedDate

问题描述

我正在使用 Spring Data JDBC

我有一个实体,其字段用 @CreatedDate@LastModifiedDate 注释。

但是,在某些情况下,我想手动设置这两个字段。

在某些情况下,有没有办法绕过 @CreatedDate@LastModifiedDate 而不从实体中删除注释?或者有没有我可以在实体被保存之前添加的回调?

解决方法

填充审核信息由 RelationalAuditingCallbackIsNewAwareAuditingHandler 完成。

第一个基本上是模块特定部分(在本例中为 Spring Data Relational)的适配器,而第二个修改实体。

您可以实现自己的 IsNewAwareAuditingHandler 变体,将其填充到 RelationalAuditingCallback 中并将其注册为 bean。不久前我在 this project on GitHub 中做了类似的事情:

@Bean
RelationalAuditingCallback isNewAwareAuditingHandler(JdbcMappingContext context) {
    return new RelationalAuditingCallback(new CustomAuditingHandler(context));
}

private static class CustomAuditingHandler extends IsNewAwareAuditingHandler {

    public CustomAuditingHandler(JdbcMappingContext context) {
        super(PersistentEntities.of(context));
    }

    @Override
    public Object markAudited(Object source) {

        if (!(source instanceof Product)) {
            return source;
        }

        Product product = (Product) source;
        if (product.createdDate == null) {
            product.createdDate = Instant.now();
        }

        return source;
    }
}

请考虑 CustomAuditingHandler 中的逻辑占位符。在那里你应该插入你的方式来确定是否手动设置值。也许您的实体实现了一个接口,将该信息作为瞬态字段提供,或者您将该信息存储在线程局部变量中。

,

如果您在 Spring Boot 上使用上述解决方案,则可以。但在使用 @EnableJdbcAuditing 时,您应该删除 @EnableJdbcAuditing。 如果使用它,则 RelationalAuditionCallback 在 ApplicationContext 上重复。

这是一个基于@Jens Schauder 想法的测试。 https://github.com/yangwansu/try-spring-data-jdbc/blob/main/src/test/java/masil/example/springdata/jdbc/ch9_14_1/ManuallySetupTest.java