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  * &lt;persistence-unit-metadata&gt;
34  *     &lt;persistence-unit-defaults&gt;
35  *         &lt;entity-listeners&gt;
36  *             &lt;entity-listener class="org.springframework.data.jpa.domain.support.AuditingEntityListener" /&gt;
37  *         &lt;/entity-listeners&gt;
38  *     &lt;/persistence-unit-defaults&gt;
39  * &lt;/persistence-unit-metadata&gt;
40  * </pre>
41  *
42  * After that it's just a matter of activating auditing in your Spring config:
43  *
44  * <pre>
45  * &#064;Configuration
46  * &#064;EnableJpaAuditing
47  * class ApplicationConfig {
48  *
49  * }
50  * </pre>
51  *
52  * <pre>
53  * &lt;jpa:auditing auditor-aware-ref="yourAuditorAwarebean" /&gt;
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