grailsgrails-ormdatabase-schemagrails-constraints

How to set uniqueness at DB level for a one-to-many association?


My problem is simple but I could not find any GORM syntax for this.

Consider the following class:

class Article {
  String text

  static hasMany = [tags: String]

  static constraints= {
    tags(unique: true) //NOT WORKING
  }

}

I want to have one unique tag name per article defined in my constraints but I cannot make it with the above syntax. Clearly I need in DB schema something like:

create table article_tags (article_id bigint, tags_string varchar(255), unique (article_id , tags_string))

How can I do that?

PS: I am also stuck for setting constraints on tag minimum and maximum size


Solution

  • FYI, you can also use a custom validator in domain classes:

        static constraints = {
        tags(validator: { 
            def valid = tags == tags.unique()
            if (!valid) errors.rejectValue(
                "tags", "i18n.message.code", "default message")
            return valid
        })
    

    At the database level, you can customize DDL generation by having the following code in grails-app/conf/hibernate/hibernate.cfg.xml:

    <hibernate-mapping>
        <database-object>
            <create>
            ALTER TABLE article_tags
            ADD CONSTRAINT article_tags_unique_constraint 
            UNIQUE(article_id, tags_string);
        </create>
            <drop>
            ALTER TABLE article_tags 
            DROP CONSTRAINT article_tags_unique_constraint;
        </drop>
        </database-object>
    </hibernate-mapping>