Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit db9ce85

Browse files
authored
Reset embedded dirty checking (#169)
* apache/grails-data-mapping#1272 Embedded object shouldn't be dirty after flush * apache/grails-data-mapping#1272 Reset dirty in embedded objects Updated GrailsEntityDirtinessStrategy.groovy to also reset dirty embedded objects.
1 parent 60b8513 commit db9ce85

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

grails-datastore-gorm-hibernate5/src/main/groovy/org/grails/orm/hibernate/dirty/GrailsEntityDirtinessStrategy.groovy

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import org.hibernate.Session
3030
import org.hibernate.engine.spi.SessionImplementor
3131
import org.hibernate.engine.spi.Status
3232
import org.hibernate.persister.entity.EntityPersister
33+
import org.slf4j.Logger
34+
import org.slf4j.LoggerFactory
3335

3436
/**
3537
* A class to customize Hibernate dirtiness based on Grails {@link DirtyCheckable} interface
@@ -42,6 +44,8 @@ import org.hibernate.persister.entity.EntityPersister
4244
@CompileStatic
4345
class GrailsEntityDirtinessStrategy implements CustomEntityDirtinessStrategy {
4446

47+
protected static final Logger LOG = LoggerFactory.getLogger(GrailsEntityDirtinessStrategy.class)
48+
4549
@Override
4650
boolean canDirtyCheck(Object entity, EntityPersister persister, Session session) {
4751
return entity instanceof DirtyCheckable
@@ -56,6 +60,30 @@ class GrailsEntityDirtinessStrategy implements CustomEntityDirtinessStrategy {
5660
void resetDirty(Object entity, EntityPersister persister, Session session) {
5761
if (canDirtyCheck(entity, persister, session)) {
5862
cast(entity).trackChanges()
63+
try {
64+
PersistentEntity persistentEntity = GormEnhancer.findEntity(Hibernate.getClass(entity))
65+
if (persistentEntity != null) {
66+
resetDirtyEmbeddedObjects(persistentEntity, entity, persister, session)
67+
}
68+
} catch (IllegalStateException e) {
69+
if (LOG.isDebugEnabled()) {
70+
LOG.debug(e.message, e)
71+
}
72+
}
73+
}
74+
}
75+
76+
private void resetDirtyEmbeddedObjects(PersistentEntity persistentEntity,
77+
Object entity,
78+
EntityPersister persister,
79+
Session session) {
80+
81+
if (DirtyCheckingSupport.areEmbeddedDirty(persistentEntity, entity)) {
82+
final associations = persistentEntity.getEmbedded()
83+
for (Embedded a in associations) {
84+
final value = a.reader.read(entity)
85+
resetDirty(value, persister, session)
86+
}
5987
}
6088
}
6189

grails-datastore-gorm-hibernate5/src/test/groovy/grails/gorm/tests/dirtychecking/HibernateDirtyCheckingSpec.groovy

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import grails.gorm.annotation.Entity
44
import grails.gorm.dirty.checking.DirtyCheck
55
import grails.gorm.transactions.Rollback
66
import org.grails.orm.hibernate.HibernateDatastore
7-
import org.springframework.transaction.PlatformTransactionManager
87
import spock.lang.AutoCleanup
98
import spock.lang.Issue
109
import spock.lang.Shared
@@ -67,6 +66,12 @@ class HibernateDirtyCheckingSpec extends Specification {
6766

6867
when:
6968
person.save(flush:true)
69+
70+
then:
71+
!person.address.hasChanged()
72+
person.address.listDirtyPropertyNames().isEmpty()
73+
74+
when:
7075
hibernateDatastore.sessionFactory.currentSession.clear()
7176
person = Person.first()
7277

0 commit comments

Comments
 (0)