See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 6.5.2.10 Custom Hibernate Types - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 2.3.8 ## 6.5.2.10 Custom Hibernate Types You saw in an earlier section that you can use composition (with the `embedded` property) to break a table into multiple objects. You can achieve a similar effect with Hibernate's custom user types. These are not domain classes themselves, but plain Java or Groovy classes. Each of these types also has a corresponding "meta-type" class that implements org.hibernate.usertype.UserType. The Hibernate reference manual has some information on custom types, but here we will focus on how to map them in Grails. Let's start by taking a look at a simple domain class that uses an old-fashioned (pre-Java 1.5) type-safe enum class:

    class Book {    String title
        String author
        Rating rating    static mapping = {
            rating type: RatingUserType
        }
    }
All we have done is declare the `rating` field the enum type and set the property's type in the custom mapping to the corresponding `UserType` implementation. That's all you have to do to start using your custom type. If you want, you can also use the other column settings such as "column" to change the column name and "index" to add it to an index. Custom types aren't limited to just a single column - they can be mapped to as many columns as you want. In such cases you explicitly define in the mapping what columns to use, since Hibernate can only use the property name for a single column. Fortunately, Grails lets you map multiple columns to a property using this syntax:

    class Book {    String title
        Name author
        Rating rating    static mapping = {
            author type: NameUserType, {
                column name: "first_name"
                column name: "last_name"
            }
            rating type: RatingUserType
        }
    }
The above example will create "first_name" and "last_name" columns for the `author` property. You'll be pleased to know that you can also use some of the normal column/property mapping attributes in the column definitions. For example:
    column name: "first_name", index: "my_idx", unique: true
The column definitions do not support the following attributes: `type`, `cascade`, `lazy`, `cache`, and `joinTable`. One thing to bear in mind with custom types is that they define the SQL types for the corresponding database columns. That helps take the burden of configuring them yourself, but what happens if you have a legacy database that uses a different SQL type for one of the columns? In that case, override the column's SQL type using the `sqlType` attribute:

    class Book {    String title
        Name author
        Rating rating    static mapping = {
            author type: NameUserType, {
                column name: "first_name", sqlType: "text"
                column name: "last_name", sqlType: "text"
            }
            rating type: RatingUserType, sqlType: "text"
        }
    }
Mind you, the SQL type you specify needs to still work with the custom type. So overriding a default of "varchar" with "text" is fine, but overriding "text" with "yes_no" isn't going to work. | Quick Reference (hide)