Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Blocker
-
Resolution: Fixed
-
Affects Version/s: 2.0.2, 2.0.3
-
Fix Version/s: 2.0.4
-
Component/s: Persistence
-
Environment:Windows 7 x64, Java 1.7.0_02 SDK, integrated tomcat
Description
After creating new project with single domain class, adding dateCreated property, and then scaffolding, cannot save new instances due to the following exception:
2012-04-02 18:03:39,949 [http-bio-8080-exec-6] ERROR StackTrace - Full Stack Trace:
org.hibernate.PropertyValueException: not-null property references a null or transient value: testapp.AutoTimestampTest.dateCreated
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:100)
at org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor.performSaveOrReplicate(ClosureEventTriggeringInterceptor.java:242)
...
Have tried explicitly setting autoTimestamp static mapping to true with no luck.
-
Hide
- TestApp.zip
- 02/Apr/12 3:14 PM
- 214 kB
- Keith Gaputis
-
- TestApp/.classpath 0.7 kB
- TestApp/.project 0.5 kB
- TestApp/.../org.codehaus.groovy.eclipse.preferences.prefs 0.1 kB
- TestApp/application.properties 0.1 kB
- TestApp/.../ApplicationResources.groovy 0.1 kB
- TestApp/grails-app/conf/BootStrap.groovy 0.1 kB
- TestApp/grails-app/.../BuildConfig.groovy 2 kB
- TestApp/grails-app/conf/Config.groovy 4 kB
- TestApp/grails-app/.../DataSource.groovy 1 kB
- TestApp/grails-app/.../resources.groovy 0.0 kB
- TestApp/grails-app/.../UrlMappings.groovy 0.2 kB
- TestApp/.../AutoTimestampTestController.groovy 4 kB
- TestApp/.../AutoTimestampTest.groovy 0.1 kB
- TestApp/grails-app/.../messages.properties 3 kB
- TestApp/.../messages_cs_CZ.properties 3 kB
- TestApp/.../messages_da.properties 3 kB
- TestApp/.../messages_de.properties 4 kB
- TestApp/.../messages_es.properties 3 kB
- TestApp/.../messages_fr.properties 2 kB
- TestApp/.../messages_it.properties 2 kB
- TestApp/.../messages_ja.properties 4 kB
- TestApp/.../messages_nl.properties 3 kB
- TestApp/.../messages_pt_BR.properties 3 kB
- TestApp/.../messages_pt_PT.properties 3 kB
- TestApp/.../messages_ru.properties 4 kB
- TestApp/.../messages_sv.properties 3 kB
- TestApp/.../messages_th.properties 6 kB
- TestApp/.../messages_zh_CN.properties 2 kB
- TestApp/grails-app/.../create.gsp 2 kB
- TestApp/grails-app/.../edit.gsp 2 kB
Activity
- All
- Comments
- Work Log
- History
- Activity
- Git Commits
I downloaded your zip, ran "grails upgrade" to upgrade it to 2.0.3 since it was 2.0.2 and everything worked correctly. I navigated to your controller and created a new instance and the dateCreated and lastUpdated properties were populated with date values automatically upon instance creation.
I'm on a Mac with 1.6.0_29 and I see you are on Windows with 1.6.0_25, so there could be something specific to Windows.
Thanks,
Bobby
I just confirmed that the issue is still occurring with grails-2.0.3. And just an FYI I am using a default, in-memory h2 data source running in dev environment.
I'm also on Windows 7 x64
In my case everithing was working in development. The I tried to deploy aplication to production.
And then it sttoped working with this error. Its funny that it only happens from time to time.
For instance I am using localisations plugin which has a feature to load resource files into db.
I was able to succesfuly update some files, but some throw this error in code from localisatios plugin.
Then I am using also activiti. Also activiti was generating this error when some process was
invoking some of my business functionality. Currently I am downgrading to 2.0.1 as I need to release my code to
production (Its a shame as version 2.0.3 resolved problem with integration testing not finding GORM methods)
I have the same problem as well on a Windows Server version 6.0 svc pck 1 box running Tomcat and grails 2.0.2. The app runs fine on the Mac. Note that I tomcat reloading set for hot deployment.
This bug can be reproduced with the test app https://github.com/domiko/bog200 of GRAILS-8433 (running with "grails prod run-war"). Bootstrap execution fails because of this exception:
org.springframework.beans.factory.access.BootstrapException: Error executing bootstraps; nested exception is org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: bog.Account.dateCreated; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: bog.Account.dateCreated at org.codehaus.groovy.grails.web.context.GrailsContextLoader.initWebApplicationContext(GrailsContextLoader.java:118) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4779) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5273) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1568) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1558) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) at java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722) Caused by: org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value: bog.Account.dateCreated; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: bog.Account.dateCreated at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:652) at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412) at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411) at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339) at org.codehaus.groovy.grails.orm.hibernate.metaclass.SavePersistentMethod.performSave(SavePersistentMethod.java:56) at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractSavePersistentMethod.doInvokeInternal(AbstractSavePersistentMethod.java:210) at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractDynamicPersistentMethod.invoke(AbstractDynamicPersistentMethod.java:63) at org.codehaus.groovy.grails.commons.metaclass.DynamicMethodInvocation$invoke.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124) at org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi.save(HibernateGormEnhancer.groovy:847) at bog.Account.save(Account.groovy) . . . Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: bog.Account.dat eCreated at org.hibernate.engine.Nullability.checkNullability(Nullability.java:100) at org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor.performSaveOrReplicate(Clo sureEventTriggeringInterceptor.java:242) at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEv entListener.java:210) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.j ava:195) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener .java:117) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java :93) at org.codehaus.groovy.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor.onSaveOrUpdate(ClosureEven tTriggeringInterceptor.java:106) at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685) at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677) at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673) at org.codehaus.groovy.grails.orm.hibernate.metaclass.SavePersistentMethod$1.doInHibernate(SavePersistentMethod. java:58) at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
The PreInsertEvent doesn't get called. Trying to debug the problem.
just getting confused with the duplicate code in ClosureEventListener & ClosureEventTriggeringInterceptor . Adding more break points and debugging again...
I debugged this now. The pre-insert listener gets called on line 249 in ClosureEventTriggeringInterceptor so it's too late since the PropertyValueException gets thrown on line 242.
240 new ForeignKeys.Nullifier(entity, false, useIdentityColumn, source)
241 .nullifyTransientReferences(values, types);
-> 242 new Nullability(source).checkNullability(values, persister, false);
243
244 if (useIdentityColumn) {
245 EntityIdentityInsertAction insert = new EntityIdentityInsertAction(
246 values, entity, persister, source, shouldDelayIdentityInserts);
247 if (!shouldDelayIdentityInserts) {
248 log.debug("executing identity-insert immediately");
-> 249 source.getActionQueue().execute(insert);
250 id = insert.getGeneratedId();
It looks like the PreInsertEventListener isn't allowed to modify the state of the object to be saved.
Maybe it's possible to modify ClosureEventTriggeringInterceptor's performSaveOrReplicate method to allow modifying values
(Object[] values = persister.getPropertyValuesToInsert(entity, getMergeMap(anything), source); is on line 220 and PreInsertEventListeners are executed on line 249.)
Looks like ClosureEventListener.synchronizePersisterState takes care of synchronizing the "Object[] values" array.
Fix committed.
TODO:
- check thread-safety of the solution (it should be since I think Hibernate copies the PreEventListeners to the session when the session is created.)
- add unit test.
Integration test added to grails-functional-tests project.
commit: https://github.com/grails/grails-functional-tests/commit/1d030a2b60022ed717dc18b7dccd5a3aac37b83c
Investigating this setting https://hibernate.onjira.com/browse/HHH-3898 (hibernate.check_nullability=false) since this fix doesn't work on PostgreSQL (because code takes different path if the primary key is generated by using a sequence or given.)
It should be safe to set check_nullability=false by default since validation should take care of null checking.
check_nullability=false doesn't help on Postgres, it just delays the problem and gives the exception from the database.
The problem is that when the PreInsertEventListener sets dateCreated, there already is an update action for the same entity in the action queue of Hibernate. Therefore dateCreated is null in the update action in this case.
I will try to modify the performSaveOrReplicate method of ClosureEventTriggeringInterceptor to never delay inserts. Currently it's done when ids are generated by a sequence. Delaying allow usage of batching.
Only certain builds fail for a certain version. This happened to us for both 2.0.1 and 2.0.3. Any way to resolve this without actually setting the dateCreated and lastUpdated values explicitly?
Before the fix is released, the only workaround seems to be to use "Date dateCreated = new Date()" and "Date lastUpdated = new Date()" in the class definition.
I am still experiencing this issue with Grails 2.1.0 against oracle 10G.
The problem doesn't seem to occur against MySql
I do not have any constraints defined for the dateCreated field
caused by: java.sql.SQLException: ORA-01407: cannot update ("ATLO10_FLAG_DB"."DISPOSITION_ENTRY"."DATE_CREATED") to NULL
I have this issue with grails 2.1.1, Postgres on domain with custom multi column hibernate type
see GRAILS-9805, bug-fix is not (yet) included in Grails 2.1 and 2.2 .
Running into this exact same thing with very basic domain classes. Tried setting autoTimestamp to true and still the same error.
Using jdk1.6.0_25 and grails-2.0.3