[hibernate-issues] [Hibernate-JIRA] Updated: (HHH-5267) NPE when updating a detached entity with a one-to-one association changed to null that is mapped with delete-orphan

Patras Vlad (JIRA) noreply at atlassian.com
Wed Jan 19 07:36:06 EST 2011


     [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-5267?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Patras Vlad updated HHH-5267:
-----------------------------

    Attachment: hibernate_HHH-5267_simpler_testcase.patch

I found it's actually easier to reproduce this issue.
All you need is an entity with a {{ManyToOne}} or {{OneToOne}} relation with {{orphanremoval=true}} and it will not work in different sessions.

In the test case, {{Employee}} has a member called {{info}} which is a one-to-one relaion to {{EmployeeInfo}}.
This code will fail:
{code}
Employee emp = new Employee();
session.save(emp);
session.evict(emp);
session.saveOrUpdate(emp);
{code}

Notice that you don't even have to set {{info}} on {{Employee}}. If the entity is detached and the relation is null, then save will fail.
It can also be from the database, if {{Employee}} does not have an associated {{EmployeeInfo}} in the database, this will also fail:
{code}
Employee emp = session.createQuery( "from Employee" ).list().get(0);
session.evict(emp);
session.saveOrUpdate(emp);
{code}

We have encountered this a couple of times since the defect was introduced. The workaround is not always easy to implement, because of the differences between {{saveOrUpdate}} and {{merge}}. Your entity might be referenced by many objects, because {{merge}} returns a new entity, you have to update all of those references, forget one and you have another bug. Sometimes you might not even have complete control on how the entity is saved, if you are using some kind of framework that automatically binds, saves and transfers entities across web request.

> NPE when updating a detached entity with a one-to-one association changed to null that is mapped with delete-orphan  
> ---------------------------------------------------------------------------------------------------------------------
>
>                 Key: HHH-5267
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5267
>             Project: Hibernate Core
>          Issue Type: Bug
>          Components: annotations, core
>    Affects Versions: 3.5.3
>         Environment: Hibernate 3.5.x
>            Reporter: Krzysztof Kowalczyk
>             Fix For: 3.6.next
>
>         Attachments: hibernate_HHH-5267_2nd_testcase.patch, hibernate_HHH-5267_simpler_testcase.patch, hibernate_HHH-5267_testcase.patch
>
>
> We use hibernate annotations and hibernate search in our project. After we moved to hibernate 3.5.2 (and 3.5.1 before that) we are having the following errors:
> java.lang.NullPointerException
> 	at org.hibernate.engine.EntityEntry.getLoadedValue(EntityEntry.java:255)
> 	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:232)
> 	at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
> 	at org.hibernate.engine.Cascade.cascade(Cascade.java:127)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:376)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:350)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
> 	at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
> 	at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
> 	at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
> 	at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
> 	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
> 	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
> 	at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:425)
> 	at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362)
> 	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338)
> 	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
> 	at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
> 	at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154)
> 	at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145)
> 	at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
> 	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
> 	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
> 	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
> 	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
> 	at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:655)
> 	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
> 	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
> 	at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
> 	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
> 	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
> 	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
> 	at $Proxy67.initializePlacowka(Unknown Source)
> In different place we have the same problem:
> [java] java.lang.NullPointerException
> [java] at org.hibernate.engine.EntityEntry.getLoadedValue(EntityEntry.java:255)
> [java] at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:232)
> [java] at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
> [java] at org.hibernate.engine.Cascade.cascade(Cascade.java:127)
> [java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:376)
> [java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:350)
> [java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
> [java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
> [java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
> [java] at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
> [java] at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
> [java] at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
> [java] at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
> [java] at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
> [java] at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
> [java] at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
> [java] at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:451)
> [java] at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
> [java] at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
> [java] at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
> [java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
> [java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
> [java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
> [java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
> [java] at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
> [java] at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
> [java] at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:665)
> The NPE is thrown because "loadedState" field is null. The exception seems to occur for instance when we have OneToOne with Cascade.DELETE_ORPHAN (or orphanRemoval="true"), CascadeType.SAVE_UPDATE and CascadeType.DELETE.
> I will try to create a simple example to reproduce the problem.

-- 
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