Skip to content

Commit 7e43a28

Browse files
authored
Merge pull request #1863 from codeconsole/9.0.x-timestampInsertOverwrite
Allow disabling of AutoTimestamp on insertion event if values are not null
2 parents d2091da + a68a7e0 commit 7e43a28

File tree

3 files changed

+80
-7
lines changed

3 files changed

+80
-7
lines changed

grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/config/Settings.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,6 @@ public interface Settings {
7070
*/
7171
String SETTING_DB_CREATE = SETTING_DATASOURCE + ".dbCreate";
7272

73+
String SETTING_AUTO_TIMESTAMP_INSERT_OVERWRITE = PREFIX + '.' + "events.autoTimestampInsertOverwrite";
74+
7375
}

grails-datastore-gorm-test/src/test/groovy/org/grails/datastore/gorm/CustomAutoTimestampSpec.groovy

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.grails.datastore.gorm
22

33
import grails.gorm.annotation.AutoTimestamp
4+
import org.grails.datastore.gorm.events.AutoTimestampEventListener
5+
46
import static grails.gorm.annotation.AutoTimestamp.EventType.*;
57
import grails.gorm.tests.GormDatastoreSpec
68
import grails.persistence.Entity
@@ -30,6 +32,65 @@ class CustomAutoTimestampSpec extends GormDatastoreSpec {
3032
r.modified != null && previousModified < r.modified
3133
previousCreated == r.created
3234
}
35+
36+
void "Test when the auto timestamp properties are already set, they are overwritten"() {
37+
when:"An entity is persisted"
38+
def r = new RecordCustom(name: "Test")
39+
def now = new Date()
40+
r.created = new Date()
41+
r.modified = r.created
42+
r.save(flush:true, failOnError:true)
43+
session.clear()
44+
r = RecordCustom.get(r.id)
45+
46+
then:"the custom lastUpdated and dateCreated are set"
47+
now < r.modified
48+
now < r.created
49+
50+
when:"An entity is modified"
51+
Date previousCreated = r.created
52+
Date previousModified = r.modified
53+
r.name = "Test 2"
54+
r.save(flush:true)
55+
session.clear()
56+
r = RecordCustom.get(r.id)
57+
58+
then:"the custom lastUpdated property is updated and dateCreated is not"
59+
r.modified != null && previousModified < r.modified
60+
previousCreated == r.created
61+
}
62+
63+
void "Test when the auto timestamp properties are already set, they are not overwritten if config is set"() {
64+
when:"An entity is persisted and insertOverwrite is false"
65+
AutoTimestampEventListener autoTimestampEventListener =
66+
RecordCustom.gormPersistentEntity.mappingContext.eventListeners.find { it.class == AutoTimestampEventListener}
67+
autoTimestampEventListener.insertOverwrite = false
68+
69+
def r = new RecordCustom(name: "Test")
70+
def now = new Date()
71+
r.created = new Date()
72+
r.modified = r.created
73+
r.save(flush:true, failOnError:true)
74+
session.clear()
75+
r = RecordCustom.get(r.id)
76+
77+
then:"the custom lastUpdated and dateCreated are not overwritten"
78+
now == r.modified
79+
now == r.created
80+
81+
when:"An entity is modified"
82+
Date previousCreated = r.created
83+
Date previousModified = r.modified
84+
r.name = "Test 2"
85+
r.save(flush:true)
86+
session.clear()
87+
r = RecordCustom.get(r.id)
88+
89+
then:"the custom lastUpdated property is updated and dateCreated is not"
90+
r.modified != null && previousModified < r.modified
91+
previousCreated == r.created
92+
}
93+
3394
@Override
3495
List getDomainClasses() {
3596
[RecordCustom]

grails-datastore-gorm/src/main/groovy/org/grails/datastore/gorm/events/AutoTimestampEventListener.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.grails.datastore.gorm.timestamp.DefaultTimestampProvider;
2424
import org.grails.datastore.gorm.timestamp.TimestampProvider;
2525
import org.grails.datastore.mapping.config.Entity;
26+
import org.grails.datastore.mapping.config.Settings;
2627
import org.grails.datastore.mapping.core.Datastore;
2728
import org.grails.datastore.mapping.engine.EntityAccess;
2829
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent;
@@ -34,6 +35,7 @@
3435
import org.grails.datastore.mapping.model.MappingContext;
3536
import org.grails.datastore.mapping.model.PersistentEntity;
3637
import org.grails.datastore.mapping.model.PersistentProperty;
38+
import org.springframework.beans.factory.annotation.Value;
3739
import org.springframework.context.ApplicationEvent;
3840

3941
/**
@@ -44,6 +46,10 @@
4446
*/
4547
public class AutoTimestampEventListener extends AbstractPersistenceEventListener implements MappingContext.Listener {
4648

49+
// if false, will not set timestamp on insert event if value is not null
50+
@Value("${" + Settings.SETTING_AUTO_TIMESTAMP_INSERT_OVERWRITE + ":true}")
51+
boolean insertOverwrite = true;
52+
4753
public static final String DATE_CREATED_PROPERTY = "dateCreated";
4854
public static final String LAST_UPDATED_PROPERTY = "lastUpdated";
4955

@@ -98,19 +104,23 @@ public boolean beforeInsert(PersistentEntity entity, EntityAccess ea) {
98104
Set<String> props = getDateCreatedPropertyNames(name);
99105
if (props != null) {
100106
for (String prop : props) {
101-
dateCreatedType = ea.getPropertyType(prop);
102-
timestamp = timestampProvider.createTimestamp(dateCreatedType);
103-
ea.setProperty(prop, timestamp);
107+
if (insertOverwrite || ea.getPropertyValue(prop) == null) {
108+
dateCreatedType = ea.getPropertyType(prop);
109+
timestamp = timestampProvider.createTimestamp(dateCreatedType);
110+
ea.setProperty(prop, timestamp);
111+
}
104112
}
105113
}
106114
props = getLastUpdatedPropertyNames(name);
107115
if (props != null) {
108116
for (String prop : props) {
109-
Class<?> lastUpdateType = ea.getPropertyType(prop);
110-
if (dateCreatedType == null || !lastUpdateType.isAssignableFrom(dateCreatedType)) {
111-
timestamp = timestampProvider.createTimestamp(lastUpdateType);
117+
if (insertOverwrite || ea.getPropertyValue(prop) == null) {
118+
Class<?> lastUpdateType = ea.getPropertyType(prop);
119+
if (dateCreatedType == null || !lastUpdateType.isAssignableFrom(dateCreatedType)) {
120+
timestamp = timestampProvider.createTimestamp(lastUpdateType);
121+
}
122+
ea.setProperty(prop, timestamp);
112123
}
113-
ea.setProperty(prop, timestamp);
114124
}
115125
}
116126
return true;

0 commit comments

Comments
 (0)