////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
////

=== Understanding Dirty Checking
In order to be as efficient as possible when it comes to generating updates GORM for MongoDb will track changes you make to persistent instances.

When an object is updated only the properties or associations that have changed will be updated.

You can check whether a given property has changed by using the `hasChanged` method:

[source,groovy]
----
if( person.hasChanged('firstName') ) {
   // do something
}
----

This method is defined by the `org.grails.datastore.mapping.dirty.checking.DirtyCheckable` trait.

In the case of collections and association types GORM for MongoDB will wrap each collection in a dirty checking aware
collection type.

One of the implications of this is if you override the collection with a non-dirty checking aware type it can disable
dirty checking and prevent the property from being updated.

If any of your updates are not updating the properties that you anticipate you can force an update using the link:../api/org/grails/datastore/mapping/dirty/checking/DirtyCheckable.html#markDirty(java.lang.String)[markDirty()] method:

[source,groovy]
----
person.markDirty('firstName')
----

This will force GORM for MongoDB to issue an update for the given property name.

==== Dirty Checking and Proxies

Dirty checking uses the `equals()` method to determine if a property has changed. In the case of associations, it is important to recognize that if the association is a proxy, comparing properties on the domain that are not related to the identifier will initialize the proxy, causing another database query.

If the association does not define `equals()` method, then the default Groovy behavior of verifying the instances are the same will be used. Because proxies are not the same instance as an instance loaded from the database, which can cause confusing behavior. It is recommended to implement the `equals()` method if you need to check the dirtiness of an association. For example:

[source, groovy]
----
class Author {
    Long id
    String name

     /**
     * This ensures that if either or both of the instances
     * have a null id (new instances), they are not equal.
     */
    @Override
    boolean equals(o) {
        if (!(o instanceof Author)) return false
        if (this.is(o)) return true
        Author that = (Author) o
        if (id !=null && that.id !=null) return id == that.id
        return false
    }
}

class Book {
    Long id
    String title
    Author author
}
----
