Showing posts with label timestamping. Show all posts
Showing posts with label timestamping. Show all posts

Tuesday, June 13, 2017

Joda Time Auto Timestamping Issue on Grails 1 1 1

Joda Time Auto Timestamping Issue on Grails 1 1 1


Ive not upgraded most of my code to Grails 1.1.1 yet so I hadnt noticed this problem until it was brought to my attention by Manuel Vio on the grails-user mailing list.

I raised a bug a few days ago around the fact that GORM identifies Joda Time types (and presumably any non-default property type) as a one-to-one association. Up to now the only problem this caused me was that it means the Joda Time plugin has to do some slightly hacky tricks in the scaffolding templates to prevent crashes when Grails tries to render the properties as though they were associated domain instances only to find they have no id property. However, on Grails 1.1.1 the bug is causing a nasty failure on auto-timestamping.

Under Grails 1.1 you can use a Joda DateTime for an auto-timestamped fields:

DateTime dateCreated
DateTime lastUpdated

static mapping = {
dateCreated type: PersistentDateTime
lastUpdated type: PersistentDateTime
}

These behave exactly like the regular Date fields with those names, i.e. theyre set automatically on save and update. In Grails 1.1.1 the same class will fail on save with a GroovyRuntimeException Could not find matching constructor for: java.lang.Object(java.lang.Long).

There is a (somewhat strange) workaround - declare the timestamped fields as non-lazy!

DateTime dateCreated
DateTime lastUpdated

static mapping = {
dateCreated type: PersistentDateTime, lazy: false
lastUpdated type: PersistentDateTime, lazy: false
}

Digging into the Grails code a little I found that association properties have their getter wrapped in a lazy-loading proxy. Since GORM thinks Joda Time properties are associations, this happens to them. The auto-timestamping code initialises the properties using property.getType().newInstance(System.currentTimeMillis()). Unfortunately, because property is actually the lazy-load proxy rather than the real property property.getType() returns Object.


Available link for download

Read more »

Tuesday, February 14, 2017

Joda Time and Grails Auto Timestamping

Joda Time and Grails Auto Timestamping


The Joda-Time Plugin docs state that Grails auto-timestamping works with Joda-Time properties which is the case. However, when testing it can be useful to take advantage of Joda Times DateTimeUtils class to mock the current time. This enables you to have new DateTime objects, for example, use a predictable timestamp. Unfortunately it doesnt play nicely with Grails auto-timestamping which under the covers uses System.currentTimeMillis(). There are a couple of solutions to this. You can disable the auto-timestamping and define your own beforeInsert event which enables you to use DateTimeUtils.setCurrentMillisFixed. For example:

static mapping = {
autoTimestamp false
}

def beforeInsert = {
dateCreated = new DateTime()
}

The other option would be to mock out the value returned by System.currentTimeMillis(). This has the advantage of meaning you dont have to add code to your domain class to enable tests to work, but on the other hand its all to easy to have such meta class modifications leak from test to test by not being torn down properly.

On a related note the next release of the Joda-Time plugin will bind additional methods to DateTimeUtils to scope mocking of the current timestamp, for example:

DateTimeUtils.withCurrentMillisFixed(aLong) {
// do some stuff that requires a mocked current time
}

No more forgetting to call DateTimeUtils.setCurrentMillisSystem() in your tearDown method!


Available link for download

Read more »