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

Gail Badner (JIRA) noreply at atlassian.com
Wed Aug 5 16:23:15 EDT 2009


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3544?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=33711#action_33711 ] 

Gail Badner commented on HHH-3544:
----------------------------------

Hi Krasimir, 

This was only fixed for merge events in HHH-3810 and released in 3.2.7 and 3.3.2. The other events that can cascade an entity save have not been fixed yet. 

You can see the fix by looking at the "FishEye" tab on HHH-3810 (http://opensource.atlassian.com/projects/hibernate/browse/HHH-3810?page=com.atlassian.jira.ext.fisheye%3Afisheye-issuepanel).

That fix (for HHH-3810) depends on the fix for HHH-3229 (http://opensource.atlassian.com/projects/hibernate/browse/HHH-3229?page=com.atlassian.jira.ext.fisheye%3Afisheye-issuepanel), so you'll need that one also.

I believe that a simlar fix will also work for these other types of events and should handle this use case properly.  I think it may be possible to modify the fix for the merge event to work polymorphically for all save events. 

Can you give either 3.2.7 or 3.3.2 a try using Session.merge() and let me know if it works?

Thanks,
Gail

> 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
>            Assignee: Gail Badner
>         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