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]

Reply via email to