Harold L. Brown
Harold L. Brown

Reputation: 9956

In Spring Data JDBC bypass @CreatedDate and @LastModifiedDate

I am using Spring Data JDBC.

I have an entity that has fields annotated with @CreatedDate and @LastModifiedDate.

However, in some cases I want to set these two fields manually.

Is there a way to bypass @CreatedDate and @LastModifiedDate in some cases without removing the annotations from the entity? Or is there a callback that I can add before the entity gets saved?

Upvotes: 1

Views: 3560

Answers (2)

Wansu yang
Wansu yang

Reputation: 66

if u use above solution on spring boot, it ok. but in use @EnableJdbcAuditing, u should remove @EnableJdbcAuditing. if it use that, RelationalAuditionCallback is dupulicated on ApplicationContext.

Here's a test based on @Jens Schauder's idea. https://github.com/yangwansu/try-spring-data-jdbc/blob/main/src/test/java/masil/example/springdata/jdbc/ch9_14_1/ManuallySetupTest.java

Upvotes: 0

Jens Schauder
Jens Schauder

Reputation: 81862

Populating the auditing information is done by the RelationalAuditingCallback and IsNewAwareAuditingHandler.

The first one basically is the adapter to the module specific part (Spring Data Relational in this case) while the second modifies the entity.

You can implement your own variant of the IsNewAwareAuditingHandler stuff it in a RelationalAuditingCallback and register it as a bean. I did something similar a short time ago in 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;
    }
}

Please consider the logic in the CustomAuditingHandler a place holder. There you should plugin your way to determine if you set the value manually. Maybe your entity implements an interface that offers that information as a transient field, or you store that information in a thread local variable.

Upvotes: 3

Related Questions