From 7089e077d5b5316389d8b8db3a524bf223a6b6bc Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Tue, 9 Jul 2019 12:00:52 +0200 Subject: [PATCH] DATAJDBC-390 - Add ordering to RelationalAuditingEventListener to run before other listeners without explicitly specified order. When an event listener is used to set an id before saving it, this ensures the auditing happens before setting the id. If this is not ensured the auditing listener doesn't consider the entity as new and doesn't set created date and created by user. Original pull request: #159. --- ...nableJdbcAuditingHsqlIntegrationTests.java | 36 +++++++++++++++++++ .../RelationalAuditingEventListener.java | 20 +++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcAuditingHsqlIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcAuditingHsqlIntegrationTests.java index ebbefa01..b523a2fd 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcAuditingHsqlIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/EnableJdbcAuditingHsqlIntegrationTests.java @@ -28,6 +28,7 @@ import java.util.function.Consumer; import org.assertj.core.api.SoftAssertions; import org.jetbrains.annotations.NotNull; import org.junit.Test; +import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -41,7 +42,9 @@ import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.auditing.DateTimeProvider; import org.springframework.data.domain.AuditorAware; import org.springframework.data.relational.core.mapping.NamingStrategy; +import org.springframework.data.relational.core.mapping.event.BeforeSaveEvent; import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Component; import org.springframework.test.context.ActiveProfiles; /** @@ -176,6 +179,23 @@ public class EnableJdbcAuditingHsqlIntegrationTests { }); } + @Test // DATAJDBC-390 + public void auditingListenerTriggersBeforeDefaultListener() { + + configureRepositoryWith( // + AuditingAnnotatedDummyEntityRepository.class, // + TestConfiguration.class, // + AuditingConfiguration.class, // + OrderAssertingEventListener.class) // + .accept(repository -> { + + AuditingAnnotatedDummyEntity entity = repository.save(new AuditingAnnotatedDummyEntity()); + + assertThat(entity.id).isNotNull(); + + }); + } + /** * Usage looks like this: *

@@ -296,4 +316,20 @@ public class EnableJdbcAuditingHsqlIntegrationTests { return () -> Optional.of("user"); } } + + /** + * An event listener asserting that it is running after {@link AuditingConfiguration#auditorAware()} was invoked and + * set the auditing data. + */ + @Component + static class OrderAssertingEventListener implements ApplicationListener { + + @Override + public void onApplicationEvent(BeforeSaveEvent event) { + + Object entity = event.getEntity(); + assertThat(entity).isInstanceOf(AuditingAnnotatedDummyEntity.class); + assertThat(((AuditingAnnotatedDummyEntity) entity).createdDate).isNotNull(); + } + } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/domain/support/RelationalAuditingEventListener.java b/spring-data-relational/src/main/java/org/springframework/data/relational/domain/support/RelationalAuditingEventListener.java index fc270b5e..6e0882e8 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/domain/support/RelationalAuditingEventListener.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/domain/support/RelationalAuditingEventListener.java @@ -18,21 +18,30 @@ package org.springframework.data.relational.domain.support; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationListener; +import org.springframework.core.Ordered; import org.springframework.data.auditing.IsNewAwareAuditingHandler; import org.springframework.data.relational.core.mapping.event.BeforeSaveEvent; /** * Spring JDBC event listener to capture auditing information on persisting and updating entities. *

- * An instance of this class gets registered when you apply {@link EnableJdbcAuditing} to your Spring config. + * An instance of this class gets registered when you enable auditing for Spring Data JDBC. * * @author Kazuki Shimizu * @author Jens Schauder * @author Oliver Gierke - * @see EnableJdbcAuditing */ @RequiredArgsConstructor -public class RelationalAuditingEventListener implements ApplicationListener { +public class RelationalAuditingEventListener implements ApplicationListener, Ordered { + + /** + * The order used for this {@link org.springframework.context.event.EventListener}. This ensures that it will run + * before other listeners without a specified priority. + * + * @see org.springframework.core.annotation.Order + * @see Ordered + */ + public static final int AUDITING_ORDER = 100; private final IsNewAwareAuditingHandler handler; @@ -45,4 +54,9 @@ public class RelationalAuditingEventListener implements ApplicationListener