Skip to content

7.0.0-RC2 BUG - mongo beforeUpdate changes not persisted #15139

@codeconsole

Description

@codeconsole

3 Solutions

1. Wrap FieldEntityAcess with ModificationTrackingEntityAccess. - Hibernate currently does something similar

#15136
This will not solve properties being marked dirty inside beforeUpdate() but will solve all calls entity access set calls inside event listeners. This will fix @AutoTimestamp.

2. Cache the Document on load and then override dirty calls. This is hibernates main mechanism. This will 2x memory usage of an entity. I have this PR ~90% complete with the exception of the original cache set call.

Hibernate does this + 1. Although doing both is probably redundant overkill and unnecessary.

3. Take a snapshot of the entity just prior to beforeUpdate() and event listeners being called, then mark any changes dirty. This is least invasive and does not have memory requirements of 2.

#15143

package mongo.test

import grails.gorm.annotation.AutoTimestamp

class User {

    String name

    Date dateCreated
    Date lastUpdated

    String random

    @AutoTimestamp(AutoTimestamp.EventType.CREATED) Date created
    @AutoTimestamp Date modified

    static constraints = {
        created nullable: true, display: false
        modified nullable: true, display: false
        random nullable: true, display: false
    }

    def beforeInsert() {
        random = "Not Updated"
    }

    def beforeUpdate() {
        random = UUID.randomUUID().toString()[0..4])
        assert isDirty('random') // throws exception in mongo, but NOT hibernate
    }
}

#15141

Hibernate Works Because:

isDirty('random') -> GormEntity.isDirty(String fieldName) -> HibernateGormInstanceApi.isDirty(D instance, String fieldName)

    boolean isDirty(String fieldName) {
        currentGormInstanceApi().isDirty(this, fieldName)
    }

HibernateGormInstanceApi compares against Hibernate's internal snapshot.

Mongo Does Not Work Because:

isDirty('random') -> GormEntity.isDirty(String fieldName) -> GormInstanceApi.isDirty(D instance, String fieldName)

GormInstanceApi does not compare against anything and only checks which properties have been specifically marked dirty.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions