Skip to content

Commit 92cd333

Browse files
kazuki43zooschauder
authored andcommitted
DATAJDBC-204 - Support for annotation based auditing.
When enabled by using @EnableJdbcAuditing entities will get properties annotated with * @createdby * @CreatedDate * @LastModifiedBy * @LastModifiedDate updated when saved. Original pull request: #64.
1 parent 9873db6 commit 92cd333

File tree

6 files changed

+487
-1
lines changed

6 files changed

+487
-1
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jdbc.domain.support;
17+
18+
import org.springframework.beans.factory.ObjectFactory;
19+
import org.springframework.context.ApplicationListener;
20+
import org.springframework.data.auditing.AuditingHandler;
21+
import org.springframework.data.jdbc.mapping.event.BeforeSaveEvent;
22+
import org.springframework.lang.Nullable;
23+
import org.springframework.util.Assert;
24+
25+
/**
26+
* Spring JDBC event listener to capture auditing information on persisting and updating entities.
27+
* <p>
28+
* You can enable this class just a matter of activating auditing using {@link org.springframework.data.jdbc.repository.config.EnableJdbcAuditing} in your Spring config:
29+
*
30+
* <pre>
31+
* &#064;Configuration
32+
* &#064;EnableJdbcRepositories
33+
* &#064;EnableJdbcAuditing
34+
* class JdbcRepositoryConfig {
35+
* }
36+
* </pre>
37+
*
38+
* @author Kazuki Shimizu
39+
* @see org.springframework.data.jdbc.repository.config.EnableJdbcAuditing
40+
* @since 1.0
41+
*/
42+
public class JdbcAuditingEventListener implements ApplicationListener<BeforeSaveEvent> {
43+
44+
@Nullable
45+
private AuditingHandler handler;
46+
47+
/**
48+
* Configures the {@link AuditingHandler} to be used to set the current auditor on the domain types touched.
49+
*
50+
* @param auditingHandler must not be {@literal null}.
51+
*/
52+
public void setAuditingHandler(ObjectFactory<AuditingHandler> auditingHandler) {
53+
Assert.notNull(auditingHandler, "AuditingHandler must not be null!");
54+
this.handler = auditingHandler.getObject();
55+
}
56+
57+
/**
58+
* {@inheritDoc}
59+
* @param event a notification event for indicating before save
60+
*/
61+
@Override
62+
public void onApplicationEvent(BeforeSaveEvent event) {
63+
if (handler != null) {
64+
event.getOptionalEntity().ifPresent(entity -> {
65+
if (event.getId().getOptionalValue().isPresent()) {
66+
handler.markModified(entity);
67+
} else {
68+
handler.markCreated(entity);
69+
}
70+
});
71+
}
72+
}
73+
74+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jdbc.repository.config;
17+
18+
import java.lang.annotation.Documented;
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Inherited;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
import org.springframework.context.annotation.Import;
26+
import org.springframework.data.auditing.DateTimeProvider;
27+
import org.springframework.data.domain.AuditorAware;
28+
29+
/**
30+
* Annotation to enable auditing in JDBC via annotation configuration.
31+
*
32+
* If you use the auditing feature, you should be configures beans of Spring Data JDBC
33+
* using {@link org.springframework.data.jdbc.repository.config.EnableJdbcRepositories} in your Spring config:
34+
*
35+
* <pre>
36+
* &#064;Configuration
37+
* &#064;EnableJdbcRepositories
38+
* &#064;EnableJdbcAuditing
39+
* class JdbcRepositoryConfig {
40+
* }
41+
* </pre>
42+
*
43+
* <p>
44+
* Note: This feature cannot use to a entity that implements {@link org.springframework.data.domain.Auditable}
45+
* because the Spring Data JDBC does not support an {@link java.util.Optional} property yet.
46+
* </p>
47+
*
48+
* @see EnableJdbcRepositories
49+
* @author Kazuki Shimizu
50+
* @since 1.0
51+
*/
52+
@Inherited
53+
@Documented
54+
@Target(ElementType.TYPE)
55+
@Retention(RetentionPolicy.RUNTIME)
56+
@Import(JdbcAuditingRegistrar.class)
57+
public @interface EnableJdbcAuditing {
58+
59+
/**
60+
* Configures the {@link AuditorAware} bean to be used to lookup the current principal.
61+
*
62+
* @return
63+
* @see AuditorAware
64+
*/
65+
String auditorAwareRef() default "";
66+
67+
/**
68+
* Configures whether the creation and modification dates are set.
69+
*
70+
* @return
71+
*/
72+
boolean setDates() default true;
73+
74+
/**
75+
* Configures whether the entity shall be marked as modified on creation.
76+
*
77+
* @return
78+
*/
79+
boolean modifyOnCreate() default true;
80+
81+
/**
82+
* Configures a {@link DateTimeProvider} bean name that allows customizing the {@link java.time.LocalDateTime} to be
83+
* used for setting creation and modification dates.
84+
*
85+
* @return
86+
* @see DateTimeProvider
87+
*/
88+
String dateTimeProviderRef() default "";
89+
90+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jdbc.repository.config;
17+
18+
import java.lang.annotation.Annotation;
19+
20+
import org.springframework.beans.factory.config.BeanDefinition;
21+
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
22+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
23+
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
24+
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
25+
import org.springframework.data.auditing.config.AuditingConfiguration;
26+
import org.springframework.data.config.ParsingUtils;
27+
import org.springframework.data.jdbc.domain.support.JdbcAuditingEventListener;
28+
29+
/**
30+
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableJdbcAuditing} annotation.
31+
*
32+
* @see EnableJdbcAuditing
33+
* @author Kazuki Shimizu
34+
* @since 1.0
35+
*/
36+
class JdbcAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
37+
38+
/**
39+
* {@inheritDoc}
40+
* @return return the {@link EnableJdbcAuditing}
41+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
42+
*/
43+
@Override
44+
protected Class<? extends Annotation> getAnnotation() {
45+
return EnableJdbcAuditing.class;
46+
}
47+
48+
/**
49+
* {@inheritDoc}
50+
* @return return "{@literal jdbcAuditingHandler}"
51+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName()
52+
*/
53+
@Override
54+
protected String getAuditingHandlerBeanName() {
55+
return "jdbcAuditingHandler";
56+
}
57+
58+
/*
59+
* (non-Javadoc)
60+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration)
61+
*/
62+
@Override
63+
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
64+
BeanDefinitionBuilder builder = super.getAuditHandlerBeanDefinitionBuilder(configuration);
65+
return builder.addConstructorArgReference("jdbcMappingContext");
66+
}
67+
68+
/**
69+
* Register the bean definition of {@link JdbcAuditingEventListener}.
70+
* {@inheritDoc}
71+
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListenerBeanDefinition(BeanDefinition, BeanDefinitionRegistry)
72+
*/
73+
@Override
74+
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
75+
BeanDefinitionRegistry registry) {
76+
Class<?> listenerClass = JdbcAuditingEventListener.class;
77+
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(listenerClass);
78+
builder.addPropertyValue("auditingHandler",
79+
ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), null));
80+
registerInfrastructureBeanWithId(builder.getRawBeanDefinition(), listenerClass.getName(), registry);
81+
}
82+
83+
}

0 commit comments

Comments
 (0)