Saturday, February 11, 2017
Persisting DateTime with zone information
Persisting DateTime with zone information
I was stuck a while ago trying to figure out how to map PersistentDateTimeTZ in a GORM class. Its an implementation of Hibernates UserType interface that persists a Joda DateTime value using 2 columns - one for the actual timestamp and one for the time zone. The DateTime class contains time zone information but a SQL timestamp column is time zone agnostic so you can lose data when the value is saved (the same exact problem exists when persisting java.util.Date values).
I could never figure out how to map the user type to my domain class property correctly. Just doing:
static mapping = {
dateTimeProperty type: PersistentDateTimeTZ
}Failed with:
org.hibernate.MappingException: property mapping has wrong number of columns.
I seem to remember someone on the Grails mailing list suggesting I tried treating the value as an embedded type. That also didnt work as GORM embedded types have to be Groovy classes in grails-app/domain and PersistentDateTimeTZ is written in Java and lives in a library jar.
I finally found the solution in the 2nd Edition of The Definitive Guide to Grails (which I cant recommend enough, by the way). The trick is to pass a closure specifying the two columns to the property definition in the mapping builder. The working code looks like this:
static mapping = {
dateTimeProperty type: PersistentDateTimeTZ, {
column name: "date_time_property_timestamp"
column name: "date_time_property_zone"
}
}The order of the columns corresponds to the order of the values returned by the sqlTypes() method of whatever UserType implementation youre using.
Available link for download