[hibernate-issues] [Hibernate-JIRA] Created: (HHH-3544) Nullability.checkNullability() throws PropertyValueException (not-null property references a null property) for a property that ForeignKeys.Nullifier.nullifyTransientReferences() just nulled

Jeppe Cramon (JIRA) noreply at atlassian.com
Fri Oct 24 08:36:04 EDT 2008


Nullability.checkNullability() throws PropertyValueException (not-null property references a null property) for a property that ForeignKeys.Nullifier.nullifyTransientReferences() just nulled
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                 Key: HHH-3544
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3544
             Project: Hibernate Core
          Issue Type: Bug
          Components: core
    Affects Versions: 3.3.1
         Environment: Hibernate 3.3.1, Hibernate Annotations 3.4, Hibernate Commons-Annotation 3.3.1, Hibernate EntityManager 3.4, PostgreSQL 8.2.5, Java 5
            Reporter: Jeppe Cramon
         Attachments: HibernateNullabilityProblem.zip

Nullability.checkNullability throws PropertyValueException (not-null property references a null property) for a property that  ForeignKeys.Nullifier.nullifyTransientReferences just nulled.

I've included an Eclipse Java project which can reproduce the problem (didn't include the jars). 
The problem requires a pretty big graph to be reproduce able. The file "Domain Model.jpg" displays the Classes that take part in the problem.
The Domain Model is a simplification of the entities from our application.

In the example, ModelTest.java, there's only one active instance entity of each type (from A to H).

With the given test case, when an instance of a is passed to entityManager.persist(..), then the following exception is thrown:

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: dk.hibernatetest.model.C.b
	at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
	at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:226)
	at dk.hibernatetest.model.ModelTest.test(ModelTest.java:49)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
	at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
	at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
	at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
	at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66)
	at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
	at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
	at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
	at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: dk.hibernatetest.model.C.b
	at org.hibernate.engine.Nullability.checkNullability(Nullability.java:95)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:313)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
	at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
	at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
	at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
	at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:636)
	at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:628)
	at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:28)
	at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:291)
	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:239)
	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
	at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:319)
	at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:265)
	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:242)
	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
	at org.hibernate.engine.Cascade.cascade(Cascade.java:153)
	at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:479)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:357)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
	at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
	at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
	at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
	at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:636)
	at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:628)
	at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:28)
	at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:291)
	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:239)
	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
	at org.hibernate.engine.Cascade.cascade(Cascade.java:153)
	at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:454)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
	at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
	at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
	at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
	at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:636)
	at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:628)
	at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:28)
	at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:291)
	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:239)
	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
	at org.hibernate.engine.Cascade.cascade(Cascade.java:153)
	at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:454)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
	at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
	at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
	at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
	at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:636)
	at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:628)
	at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:28)
	at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:291)
	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:239)
	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
	at org.hibernate.engine.Cascade.cascade(Cascade.java:153)
	at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:454)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
	at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
	at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
	at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
	at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:636)
	at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:628)
	at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:28)
	at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:291)
	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:239)
	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
	at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:319)
	at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:265)
	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:242)
	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
	at org.hibernate.engine.Cascade.cascade(Cascade.java:153)
	at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:479)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:357)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
	at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
	at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
	at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
	at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
	at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:645)
	at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:619)
	at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:623)
	at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:220)
	... 21 more


As noted in TestModel.java, if some of the other entities (namely c, g or h) are passed to persist(), then the problem doesn't occur.
I've tried to debug the problem and the only difference I've seen inside ForeignKeys.Nullifier.nullifyTransientReferences() is that, in the cases where an exception is thrown, then the B instance that C.b points to has the state SAVING, whereas when the exception isn't thrown, then it has state MANAGED.

When the B instance has state SAVING, then ForeignKeys.Nullifier.nullifyTransientReferences() nulls then entry in it's value array.
After that, Nullability.checkNullability(), performs a null check, which fails because ForeignKeys.Nullifier.nullifyTransientReferences() just nulled the property in the values array.
Could it be a solution to reverse the order of the ForeignKeys.Nullifier.nullifyTransientReferences()  and  Nullability.checkNullability()  (See AbstractEventListener.performSaveOrReplicate(...)) 
or does ForeignKeys.Nullifier.nullifyTransientReferences() instead have to take nullability into considerations?

/Jeppe

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list