apache / apache/grails-core

Entities inside embedded collections don't track changes

Open
#14,388 1 comment 0 reactions 0 assignees View on GitHub
relates-to: grails-data-mongodb
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

Here is an example project:

https://github.com/valentingoebel/grails-dirtycheckingbug/

application.yml requires following env variables so make sure you fill them.

```yaml
grails:
mongodb:
host: ${MONGODB_HOST}
port: 27017
username: ${MONGODB_USER}
password: ${MONGODB_PASS}
databaseName: grailsdirtycheckingbug
```

Here is a summary of the code:

```groovy
class DBList {

static constraints = {
}

List entries = []
static embedded = ['entries']

static hasMany = [
entries: DBListEntry
]
}

class DBListEntry {

String value

static constraints = {
}
}

class DBListController {

def index(Integer max) {
def dblist = DBList.list()[0]

dblist.entries.each { it ->
it.value = it.value + "1"
render "DBListEntry: This should be dirty but it isn't: ${it.listDirtyPropertyNames()}
"
}

render "DBList: This is not dirty (optional bug): ${dblist.listDirtyPropertyNames()}

"

dblist.entries.each { it ->
it.trackChanges()
}

dblist.entries.each { it ->
it.value = it.value + "2"
render "DBListEntry: It works!: ${it.listDirtyPropertyNames()}
"
}

render "DBList: This is not dirty (optional bug): ${dblist.listDirtyPropertyNames()}

"

render "Output: ${dblist.entries*.value}
"
}
}
```
1. Calling `trackChanges()` on each entity inside the embedded list results in the desired outcome. I am already using this workaround in my projects but it required substantial changes in my code because using databinding in controller parameters like `def show(DBList list)` will fill each field before you even get an opportunity to call trackChanges().

2. Even with `trackChanges()` there is still the issue that the list itself does not get marked as dirty. This is fine in the non embedded case because changing an entity would mark all its associated entities dirty which is certainly not what we want but for embedded entities it could make sense because an embedded entity is always contained inside a parent entity. Therefore changing the child could be interpreted as a change in the parent.

I only need the first bug fixed because it prevents me from using databinding in controller parameters. The second one is up for discussion and can be rejected if it doesn't make sense. Marking a list dirty when at least one of its elements has changed is very easy so I'm not really insisting on that change.

Contributor guide

Open the contributing guide

Research direction

Start with the embedded DBList and DBListEntry definitions and the DBListController example, using application.yml to configure MongoDB and the required environment variables. Reproduce the databinding path and verify that changing an embedded entry tracks its dirty properties without explicitly calling trackChanges().

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy, mongodb
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.