1 /*
2 * Copyright 2008-2020 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 * https://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.jpa.domain.support;
17
18 import javax.persistence.PrePersist;
19 import javax.persistence.PreUpdate;
20
21 import org.springframework.beans.factory.ObjectFactory;
22 import org.springframework.beans.factory.annotation.Configurable;
23 import org.springframework.data.auditing.AuditingHandler;
24 import org.springframework.data.domain.Auditable;
25 import org.springframework.lang.Nullable;
26 import org.springframework.util.Assert;
27
28 /**
29 * JPA entity listener to capture auditing information on persiting and updating entities. To get this one flying be
30 * sure you configure it as entity listener in your {@code orm.xml} as follows:
31 *
32 * <pre>
33 * <persistence-unit-metadata>
34 * <persistence-unit-defaults>
35 * <entity-listeners>
36 * <entity-listener class="org.springframework.data.jpa.domain.support.AuditingEntityListener" />
37 * </entity-listeners>
38 * </persistence-unit-defaults>
39 * </persistence-unit-metadata>
40 * </pre>
41 *
42 * After that it's just a matter of activating auditing in your Spring config:
43 *
44 * <pre>
45 * @Configuration
46 * @EnableJpaAuditing
47 * class ApplicationConfig {
48 *
49 * }
50 * </pre>
51 *
52 * <pre>
53 * <jpa:auditing auditor-aware-ref="yourAuditorAwarebean" />
54 * </pre>
55 *
56 * @author Oliver Gierke
57 * @author Thomas Darimont
58 * @author Christoph Strobl
59 * @author Mark Paluch
60 */
61 @Configurable
62 public class AuditingEntityListener {
63
64 private @Nullable ObjectFactory<AuditingHandler> handler;
65
66 /**
67 * Configures the {@link AuditingHandler} to be used to set the current auditor on the domain types touched.
68 *
69 * @param auditingHandler must not be {@literal null}.
70 */
71 public void setAuditingHandler(ObjectFactory<AuditingHandler> auditingHandler) {
72
73 Assert.notNull(auditingHandler, "AuditingHandler must not be null!");
74 this.handler = auditingHandler;
75 }
76
77 /**
78 * Sets modification and creation date and auditor on the target object in case it implements {@link Auditable} on
79 * persist events.
80 *
81 * @param target
82 */
83 @PrePersist
84 public void touchForCreate(Object target) {
85
86 Assert.notNull(target, "Entity must not be null!");
87
88 if (handler != null) {
89
90 AuditingHandler object = handler.getObject();
91 if (object != null) {
92 object.markCreated(target);
93 }
94 }
95 }
96
97 /**
98 * Sets modification and creation date and auditor on the target object in case it implements {@link Auditable} on
99 * update events.
100 *
101 * @param target
102 */
103 @PreUpdate
104 public void touchForUpdate(Object target) {
105
106 Assert.notNull(target, "Entity must not be null!");
107
108 if (handler != null) {
109
110 AuditingHandler object = handler.getObject();
111 if (object != null) {
112 object.markModified(target);
113 }
114 }
115 }
116 }
117