35

I am new to spring and I am confused how @CreatedDate annotation works in an entity.

I did a google search and there were many solutions, but none of them worked for me except one. I am confused why?

This is what I tried first

@Entity
@EntityListeners(AuditingEntityListener.class)
public class User implements Serializable {

    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @CreatedDate
    private Date created;

    public User(String name) {

        this.name = name;
    }

    public User() {
    }

It did not work. I got NULL for the value in created column.

Then I did this.

@Entity
@EntityListeners(AuditingEntityListener.class)
public class User implements Serializable {

    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @CreatedDate
    private Date created = new Date();

    public User(String name) {

        this.name = name;
    }

    public User() {
    }

This actually stored the time stamp in the db. My question is most of the tutorials I followed suggested that I do not need new Date() to get the current time stamp. Looks like I do need that. Is there anything I am missing?

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Fawzan
  • 4,738
  • 8
  • 41
  • 85
  • Did you try this ? http://stackoverflow.com/questions/20483841/spring-data-createddate-annotation-doesnt-work-for-me – Vasu Nov 02 '16 at 00:49

6 Answers6

69

I was Having this issue also and your solution helped me, Thanks, And I add some other annotations to work

Fist make sure you put in SpringApplication Configuration

@SpringBootApplication
@EnableJpaAuditing

Second, make sure you use this annotation on your needed entities

  @Entity
  @Table
  @EntityListeners(AuditingEntityListener.class)
Ismail
  • 1,668
  • 1
  • 15
  • 10
  • 3
    Thank you , this helped me resolve the `@CreatedDate` annotation not working. It is not advisable to use this annotation along with `@SpringBootApplication` . I had the following error while testing : _java.lang.IllegalArgumentException: JPA metamodel must not be empty!_ . Please read through [this](https://stackoverflow.com/a/60608499/4214241) answer as well . One should make sure the unrelated slices wont interfere while testing as well. – R.G Apr 12 '20 at 14:13
30

The @CreatedDate won't work by itself if you just put @EntityListeners(AuditingEntityListener.class) on your entities. In order, it'll work you have to do a little more configuration.

Let's say that in your DB the field of @CreatedDate is String type, and you want to return the user that is currently logged in as a value for @CreatedDate, then do this:

public class CustomAuditorAware implements AuditorAware<String> {

    @Override
    public String getCurrentAuditor() {
        String loggedName = SecurityContextHolder.getContext().getAuthentication().getName();
        return loggedName;
    }

}

You can write there any functionality that fits your needs, but you certainly must have a bean that reference to a class that implements `AuditorAware

The second part and equally important, is to create a bean that returns that class with annotation of @EnableJpaAuditing, like this:

@Configuration
@EnableJpaAuditing
public class AuditorConfig {

    @Bean
    public CustomAuditorAware auditorProvider(){
        return new CustomAuditorAware();
    }
}

if your poison is XML configuration then do this:

<bean id="customAuditorAware" class="org.moshe.arad.general.CustomAuditorAware" />
    <jpa:auditing auditor-aware-ref="customAuditorAware"/>
Moshe Arad
  • 3,587
  • 4
  • 18
  • 33
  • 6
    I have the same config, but this sets values to `@CreatedBy` and `@LastModifiedBy` annotated field. Other fields that annotated as `@LastModifiedDate` and `@CreatedDate` is always null. How to fix this? – Oleksandr H Jul 30 '17 at 11:51
  • Did you try what it says here: https://stackoverflow.com/a/50948632/986160 – Michail Michailidis Jan 14 '19 at 15:01
  • for me it was required to pass AuditorAware ref even while using annotations: `@EnableJpaAuditing(auditorAwareRef = "auditorProvider")` where auditorProvider - @Bean function providing the AuditorAware instance – Mohamed Iqzas Apr 04 '22 at 02:05
12

You can use @creationTimestamp and @UpdateTimestamp like this:

  @CreationTimestamp
  private Instant createdAt;

  @UpdateTimestamp
  private Instant updatedAt;
mrek
  • 1,655
  • 1
  • 21
  • 34
2

If you want to use java8 time classes:

@EnableJpaAuditing(dateTimeProviderRef = "auditingDateTimeProvider")
....

@Bean(name = "auditingDateTimeProvider")
public DateTimeProvider dateTimeProvider() {
        return () -> Optional.of(OffsetDateTime.now());
}
Sarvar Nishonboyev
  • 12,262
  • 10
  • 69
  • 70
2

Without using JPA Entity listener, create date will not work as this is how JPA work for auditing and create or modify date.

just modify code like below:

@Entity
@EntityListeners(AuditingEntityListener.class)
class XYZ {

    @Setter(value = AccessLevel.NONE)
    @CreatedDate
    @Column(name = "date_time")
    private Date dateTime;


}
arjun kumar
  • 467
  • 5
  • 12
0

Add @EnableMongoAuditing or @EnableJpaAuditing as per your code