-
-
Notifications
You must be signed in to change notification settings - Fork 964
7.0.0-RC2 BUG FIX - @AutoTimestamp Mongo Persistence #15122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,13 +32,15 @@ | |
|
||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.ApplicationEvent; | ||
import org.springframework.util.ReflectionUtils; | ||
|
||
import grails.gorm.annotation.AutoTimestamp; | ||
import org.grails.datastore.gorm.timestamp.DefaultTimestampProvider; | ||
import org.grails.datastore.gorm.timestamp.TimestampProvider; | ||
import org.grails.datastore.mapping.config.Entity; | ||
import org.grails.datastore.mapping.config.Settings; | ||
import org.grails.datastore.mapping.core.Datastore; | ||
import org.grails.datastore.mapping.dirty.checking.DirtyCheckable; | ||
import org.grails.datastore.mapping.engine.EntityAccess; | ||
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent; | ||
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener; | ||
|
@@ -148,10 +150,25 @@ private void initializeIfNecessary(PersistentEntity entity, String name) { | |
public boolean beforeUpdate(PersistentEntity entity, EntityAccess ea) { | ||
Set<String> props = getLastUpdatedPropertyNames(entity.getName()); | ||
if (props != null) { | ||
Object entityObject = ea.getEntity(); | ||
boolean isDirtyCheckable = entityObject instanceof DirtyCheckable; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. instanceof is incompatible with Hibernate Proxies |
||
|
||
// For dirty-checking datastores (e.g., MongoDB), only set autotimestamp if entity has dirty properties | ||
if (isDirtyCheckable) { | ||
List<String> dirtyPropertyNames = ((DirtyCheckable) entityObject).listDirtyPropertyNames(); | ||
if (dirtyPropertyNames.isEmpty()) { | ||
return true; | ||
} | ||
} | ||
|
||
for (String prop : props) { | ||
Class<?> lastUpdateType = ea.getPropertyType(prop); | ||
Object timestamp = timestampProvider.createTimestamp(lastUpdateType); | ||
ea.setProperty(prop, timestamp); | ||
// Mark property as dirty for datastores that use dirty checking (e.g., MongoDB) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand this is a mongo specific, but hibernate does have dirty checking and works. What makes hibernate different here? |
||
if (isDirtyCheckable) { | ||
((DirtyCheckable) entityObject).markDirty(prop); | ||
} | ||
} | ||
} | ||
return true; | ||
|
@@ -167,18 +184,6 @@ protected Set<String> getDateCreatedPropertyNames(String entityName) { | |
return properties == null ? null : properties.orElse(null); | ||
} | ||
|
||
private static Field getFieldFromHierarchy(Class<?> entity, String fieldName) { | ||
Class<?> clazz = entity; | ||
while (clazz != null) { | ||
try { | ||
return clazz.getDeclaredField(fieldName); | ||
} catch (NoSuchFieldException e) { | ||
clazz = clazz.getSuperclass(); | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
protected void storeDateCreatedAndLastUpdatedInfo(PersistentEntity persistentEntity) { | ||
if (persistentEntity.isInitialized()) { | ||
ClassMapping<?> classMapping = persistentEntity.getMapping(); | ||
|
@@ -190,13 +195,15 @@ protected void storeDateCreatedAndLastUpdatedInfo(PersistentEntity persistentEnt | |
} else if (property.getName().equals(DATE_CREATED_PROPERTY)) { | ||
storeTimestampAvailability(entitiesWithDateCreated, persistentEntity, property); | ||
} else { | ||
Field field = getFieldFromHierarchy(persistentEntity.getJavaClass(), property.getName()); | ||
if (field != null && field.isAnnotationPresent(AutoTimestamp.class)) { | ||
AutoTimestamp autoTimestamp = field.getAnnotation(AutoTimestamp.class); | ||
if (autoTimestamp.value() == AutoTimestamp.EventType.UPDATED) { | ||
storeTimestampAvailability(entitiesWithLastUpdated, persistentEntity, property); | ||
} else { | ||
storeTimestampAvailability(entitiesWithDateCreated, persistentEntity, property); | ||
Field field = ReflectionUtils.findField(persistentEntity.getJavaClass(), property.getName()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're trying to target a bug fix, why switch to a different method of resolution? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jdaugherty because it is does exactly same thing. |
||
if (field != null) { | ||
if (field.isAnnotationPresent(AutoTimestamp.class)) { | ||
AutoTimestamp autoTimestamp = field.getAnnotation(AutoTimestamp.class); | ||
if (autoTimestamp.value() == AutoTimestamp.EventType.UPDATED) { | ||
storeTimestampAvailability(entitiesWithLastUpdated, persistentEntity, property); | ||
} else { | ||
storeTimestampAvailability(entitiesWithDateCreated, persistentEntity, property); | ||
} | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you just trying to minimize updates by removing this statement?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdaugherty yes, updates should be uniform in 1 location.