dateCreated, lastUpdated fields in Grails 2.0
-
04-12-2019 - |
Pergunta
I've got an application that was using Grails 1.3.7 which I've just migrated to Grails 2.0. The application makes use of the automatic dateCreated
and lastUpdated
fields to manage the timestamps associated with creation and modification of the objects. After upgrading, I get the following error:
| Running Grails application
| Error 2012-01-29 22:36:53,504 [Thread-8] ERROR util.JDBCExceptionReporter - ERROR: null value in column "date_created" violates not-null constraint
| Error 2012-01-29 22:36:53,510 [Thread-8] ERROR events.PatchedDefaultFlushEventListener - Could not synchronize database state with session
Commenting out the above mentioned fields in my Domain Classes makes the problem go away.
Have the dateCreated
and lastUpdated
fields been deprecated in Grails 2.0? If so, does that mean that I have to write the code to handle this functionality manually or has the code been moved to a plugin of some sort, like the audit-trail plugin?
Solução
Ok, fixed it by manually setting the autoTimestamp variable to "true" in the domain class definitions:
static mapping = {
autoTimestamp true
}
I would guess that this property is not set after migrating a project from Grails 1.3.7 to 2.0.0.
Outras dicas
Grails 2.0 still supports the automatic timestamps. It's listed in the manual (scroll up a bit from this link).
However, it specifically mentions:
If you put
nullable: false
constraints on eitherdateCreated
orlastUpdated
, your domain instances will fail validation - probably not what you want. Leave constraints off these properties unless you have disabled automatic timestamping.
There is a bug in Grails 2.0.3 that can cause this problem when using Postgres. See http://jira.grails.org/browse/GRAILS-8988. The issue says it will resolved when 2.0.4 is released.
I found an alternate solution if you're working in Grails 4:
class ScheduledTaskServiceSpec extends Specification implements ServiceUnitTest<ScheduledTaskService>{
@Shared @AutoCleanup HibernateDatastore hibernateDatastore
@Shared AutoTimestampEventListener timestamper
void setupSpec() {
hibernateDatastore = new HibernateDatastore(RegistrationCode)
timestamper = hibernateDatastore.getAutoTimestampEventListener()
}
@Transactional
@Rollback
void 'some test method'() {
when:
timestamper.withoutDateCreated(MyDomainClass) {
MyDomainClass mdc = new MyDomainClass(name:"foo")
mdc.dateCreated = new Date() - 20
}
then:
MyDomainClass.findByName("foo").dateCreated < new Date()
}
}