Entities inside embedded collections don't track changes
- 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
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