diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b84745d..467d9d41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ ### 💥 Breaking Changes (upgrade difficulty: 🟢 LOW - requires Java 17 for Hazelcast) +### 🐞 Bug Fixes + +* Fixed `JsonBlob` unique name validation which also affected `Views`. + ### ⚙️ Technical * Minor Grails upgrades * Hazelcast upgrade 5.3.7 -> 5.5.0 diff --git a/grails-app/domain/io/xh/hoist/jsonblob/JsonBlob.groovy b/grails-app/domain/io/xh/hoist/jsonblob/JsonBlob.groovy index 366b7276..c5a8ccf8 100644 --- a/grails-app/domain/io/xh/hoist/jsonblob/JsonBlob.groovy +++ b/grails-app/domain/io/xh/hoist/jsonblob/JsonBlob.groovy @@ -41,7 +41,9 @@ class JsonBlob implements JSONFormat { type maxSize: 50, blank: false owner maxSize: 50, nullable: true, blank: false acl nullable: true - name maxSize: 255, blank: false, unique: ['owner', 'type', 'archivedDate'] + name maxSize: 255, blank: false, validator: { val, obj -> + isNameUnique(val, obj) ?: 'default.not.unique.message' + } value validator: {Utils.isJSON(it) ?: 'default.invalid.json.message'} meta nullable: true, validator: {Utils.isJSON(it) ?: 'default.invalid.json.message'} description nullable: true @@ -90,4 +92,27 @@ class JsonBlob implements JSONFormat { return ret } + + //------------------- + // Implementation + //------------------- + private static boolean isNameUnique(String blobName, JsonBlob blob) { + // Unique constraint validation across nullable fields can be unreliable. + // See https://github.com/grails/grails-data-mapping/issues/1585 + !(blob.owner != null ? + where { + name == blobName && + type == blob.type && + archivedDate == blob.archivedDate && + owner == blob.owner && + token != blob.token + } : + where { + name == blobName && + type == blob.type && + archivedDate == blob.archivedDate && + owner == null && + token != blob.token + }) + } }