[hibernate-issues] [Hibernate-JIRA] Updated: (HHH-3544) Nullability.checkNullability() throws PropertyValueException (not-null property references a null property) for a property that ForeignKeys.Nullifier.nullifyTransientReferences() just nulled
Krasimir Chobantonov (JIRA)
noreply at atlassian.com
Mon Mar 2 20:46:38 EST 2009
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3544?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Krasimir Chobantonov updated HHH-3544:
--------------------------------------
Attachment: 3.3.1.GA-HHH-3544.v3.patch
Attaching patch 3 that should also take care of the cascade deletes...
Krasimir
> 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: 3.3.1.GA-HHH-3544, 3.3.1.GA-HHH-3544.v2.patch, 3.3.1.GA-HHH-3544.v3.patch, 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