Georgian Citizen
Georgian Citizen

Reputation: 3957

Grails Unique Constraint

I have a grails application using hibernate.Under grails 1.3.7 everything works properly, but when I switch to grails 2.0.3 the following problem appears:

I can't check for unique fields under java/src directory. If I try to add or update any record with the same unique key, batch insert error appears.

Under src/groovy I create a class to check validation:

Example: LanguageCommand.groovy

package myproject.command

import org.codehaus.groovy.grails.validation.Validateable;

@Validateable
class LanguageCommand {

    String code
    String codeDescription

    static constraints= {
        code(blank:false, maxSize:50)
        codeDescription(maxSize:200)
    }
}

and under src/java I create a class to check for unique fields

Example: LanguageConstraints.groovy

package myproject.model

    constraints = {
        code unique: true
    }

where myproject.model is the name of the package that contains hibernate classes.

Note: Validation class works fine but the unique one not. i try to add unique constraints to validation class, same error appears

Error:

Error 500: Executing action [save] of controller 
           [myproject.controller.LanguageController] 
           caused exception: Runtime error executing action
Servlet: grails
URI: /myproject/grails/language/save.dispatch
Exception Message: Batch entry 0 insert into language 
                   (language_code, code_description, version, id) 
                   values (en, English, 0, 1) was aborted. 
                   Call getNextException to see the cause.
Caused by: Batch entry 0 insert into language 
           (language_code, code_description, version, id) 
           values (en, English, 0, 1) was aborted. 
           Call getNextException to see the cause.
Class: LanguageController
At Line: [125]
Code Snippet:

Any help?

Upvotes: 0

Views: 1609

Answers (2)

Eugeny Pozharsky
Eugeny Pozharsky

Reputation: 1

In Grails 2, unique constraints may be applied only for GORM domains (gorm mappings), but not to Hibernate domains (hibernate mappings). Appropriate validator was added in grails. See isValid method of AbstractPersistentConstraint class.

Grails 1.3.x didn't checks this.

Upvotes: 0

user597987
user597987

Reputation:

Under src/groovy you will create a LanguageCommand.groovy class:

package myproject.command

import org.codehaus.groovy.grails.validation.Validateable;

@Validateable
class LanguageCommand {
    String oldCode
    String code
    String codeDescription

    static constraints= {
        code(maxSize:40, blank:false, validator: { val, obj ->
            if((obj.oldCode != val) && (Language.findWhere(code:val) != null))
                return['constraints.unique.code']
        })
        codeDescription(maxSize:200)
    }
}

and in i18n/messages.properties you must write (the message you want to display it):

constraints.unique.code = code must be unique

and in the controller in update method before check of validation you must write:

def update = {  
    LanguageCommand languageCommand ->
    Language languageInstance = Language.get(params.id)
    if(languageInstance) {
        languageCommand.oldCode = languageInstance.code
        if (!languageCommand.validate()){
            ...
            ...
        }
        ...
        ...
    }
    ...
    ...
}

Note: oldCode is a used in update only not in create, we store in it the code before updating, because if we search language by the code without changing it it return a result, then when the code = equal old code i we didn't search language by code.

hope this help you

Upvotes: 2

Related Questions