dpcasady opened a new issue, #14540:
URL: https://github.com/apache/grails-core/issues/14540
The detailed functionality (especially in edge cases dealing with
inheritance) of unique constraints has changed back and forth over the last
couple of years. As of 6.1.11, this behavior has changed again.
### Task List
- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [x] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)
### Steps to Reproduce
1. Create a parent domain class with at least one field (e.g., `name`)
2. Create 2 child domain classes that each define a unique constraint for
the inherited name field
3. Create an instance of each child class and set their name fields to the
same value
4. Persist both instances
Here's an example of what the domains might look like:
```
class Parent {
String name
}
class Child1 extends Parent {
static constraints = {
name unique: true
}
}
class Child2 extends Parent {
static constraints = {
name unique: true
}
}
```
And the unexpected behavior:
```
def child1 = new Child1(name: 'test').save()
def child2 = new Child2(name: 'test').save() // validation fails
```
### Expected Behaviour
Although the `name` field is declared in the parent class, the unique
constraints are defined in the child classes, so one would expect that only
duplicate values within the same child class would cause validation to fail.
When searching for duplicate instances, it shouldn't matter where the field is
declared, only where the constraint is defined. This is how things have worked
as of late up until 6.1.11.
### Actual Behaviour
In reality, the unique constraint finds the class that declares the
constrained property and assumes that that class is also the one that defines
the constraint. After persisting an instance of one child class, an instance of
the other child class with the same `name` value fails validation. This would
be the expected behavior if the constraint was also defined in the parent
class, but that's not the case.
Unfortunately, [the
fix](https://github.com/grails/grails-data-mapping/pull/1164/commits/216bd57cbcf741811d9c67856068c9d3af0ec329#diff-a793125965a7cc38861712786135eb23R59)
for a recent
[issue](https://github.com/grails/grails-data-mapping/issues/1162) caused this
issue to arise. I can see how this is a tricky problem. Constraints should have
the ability to be inherited, but i don't believe that we should assume that the
class that declares the field also defines the constraint. Currently, a
constraint only has a reference to the constraint owning class, but not to the
constraint defining class. If there was a reference to the constraint defining
class, we could check if the constraint defining class and the class that
declares the field are the same before automatically using the class that
declares the field in the unique constraint criteria.
I'd be happy to work on a pull request but wanted to get some feedback first.
### Environment Information
- **Operating System**: MacOS
- **GORM Version:** 6.1.11
- **Grails Version (if using Grails):** 3.3.8
- **JDK Version:** 1.8
### Example Application
https://github.com/dpcasady/unique-constraint-inheritance
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]