2

I created the following Entity and test it using h2:

@Getter
public class Topic {

    @Id
    private long id;

    private final Title title;

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime lastModified;

    // ...
}

The TopicRepository is an empty interface.

The following test fails with the error that createdAt is null:

@RunWith(SpringRunner.class)
@SpringBootTest
public class BasicRepositoryTests {

    @Autowired
    TopicRepository topicRepository;

    @Test
    public void topicRepositoryWorks() {
        val topic = new Topic();
        val savedTopic = topicRepository.save(topic);

        assertEquals(1, topicRepository.count());
        assertNotNull(savedTopic.getLastModified(), "lastModified must be set");
        assertNotNull(savedTopic.getCreatedAt(), "createdAt must be set");

        topicRepository.delete(savedTopic);

        assertEquals(0, topicRepository.count());
    }

}

My Application is annotated with @SpringBootApplication and @EnableJdbcAuditing.

Why is createdAt still null, lastModified on the other hand is not null?

Edit

I changed the types of Topic.createdAt and Topic.lastModified to Instant, which did not work.

Also, I added the following method, which, I guess, should provide values for the Instant fields:

@Bean
public AuditorAware<Instant> instantAuditorAware() {
    return () -> Optional.of(Instant.now());
}

Sadly, although the method gets called, createdAt is still null.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
Joshua
  • 2,932
  • 2
  • 24
  • 40
  • Possible duplicate of [@CreatedDate annotation does not work with mysql](https://stackoverflow.com/questions/40370709/createddate-annotation-does-not-work-with-mysql) – Sudhir Ojha Jun 11 '19 at 11:51
  • @SudhirOjha thanks for your Reply. I hope, that it isn't a duplicate since I want to work with `spring-data-jdbc`, not `jpa`. – Joshua Jun 11 '19 at 12:11
  • Could you create a github repository reproducing this? – Jens Schauder Jun 12 '19 at 05:16
  • I created a project to demonstrate my case, and shit worked. Before writing this question, I worked with `UUID`s instead of `long`s and implemented a `BeforeSave` event listener to create them. Could it be that it interfered with anything regarding the `CreatedDate` annotation, maybe swallowing the event? – Joshua Jun 12 '19 at 08:59
  • @JensSchauder I uploaded my demo project here: github.com/joshavg/created-at-sdjdbc The child entity of the Aggregate, Reply, does not get a CreatedDate written. Could that be, because child entities get deleted first, then reinserted on modification? – Joshua Jun 12 '19 at 10:44
  • That does not match the question you asked. Creation and modification date only get set on the aggregate root (`Topic`). – Jens Schauder Jun 12 '19 at 12:27

1 Answers1

3

Auditing annotations get only considered for the aggregate root. If auditing information is needed for entities that are part of an aggregate but not the aggregate root this can be done by implementing it in the aggregate root which should manage all changes to it and the entities of the aggregate.

While the source code posted in the question suggests that you are actually looking at the aggregate root the code you made available via Github shows that the annotation on the root works fine but on the non root entity doesn't as described above.

You don't need an AuditorAware bean. That is only needed for @CreatedBy and @LastModifiedBy.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348