Wednesday, August 18, 2010

Criteria queries don't work properly with Grails Enums

Looks like Grails (as of version 1.3.1) still didn't fix all the issues with Enums.

I'm using a criteria query like this:

c = MyDomainClass.createCriteria()
def list = c.list {
    and {
        classAttr {
            eq ("attr1", param1)
        }
        eq ("enumAttr", param2)
    }
} 

In this case, MyDomainClass.enumAttr represents an enum. It looks something like this:

enum CountryEnum {
    AUSTRIA("austria")
    BRAZIL("brazil")
    CANADA("canada")

    String name

    CountryEnum(String name) {
        this.name = name
    }
}

Grails, quite wisely, stores 'AUSTRIA', 'BRAZIL', and 'CANADA' in the DB.
However, the above criteria query generates the following error:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum

There a little section about Enums in Grails 1.1 release notes, which mentions that the value attribute should now be named 'id'. However switching 'name' to 'id' in my CountryEnum simply got rid of the exception, but the 'list' was still empty after the query completed. Extracting SQL from Hibernate debug output produced valid results, which means the problem lies somewhere in the Hibernate layer. Also DB values became 'austria', 'brazil', and 'canada', which are the values of 'id'.

Dynamic finders seem to handle Enums pretty well, but evidently the problem still exists when using Criteria or HQL.

No comments:

Post a Comment