[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-5039) Entity added instead of replaced in StateFullPersistenceContext during an update

Ed Bras (JIRA) noreply at atlassian.com
Tue Mar 30 11:23:32 EDT 2010


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

Ed Bras commented on HHH-5039:
------------------------------

Sorry, little slip of the pen. I my last comment I mean "You" of course instead of "I".


> Entity added instead of replaced in StateFullPersistenceContext during an update
> --------------------------------------------------------------------------------
>
>                 Key: HHH-5039
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5039
>             Project: Hibernate Core
>          Issue Type: Bug
>    Affects Versions: 3.3.2
>         Environment: Windows 7
>            Reporter: Ed Bras
>
> Hibernate bug (version: 3.3.2):
> Entity added instead of replaced in StateFullPersistenceContext during an update.
> Exception that occurs (only the interesting parts):
> ----
> Caused by: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.bv.core.domain.category.impl.IncomeInfoDefault.wage
> 	at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:58)
> 	at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:87)
> 	at org.hibernate.type.ComponentType.getPropertyValue(ComponentType.java:366)
> 	at org.hibernate.tuple.entity.AbstractEntityTuplizer.getComponentValue(AbstractEntityTuplizer.java:335)
> 	at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValue(AbstractEntityTuplizer.java:306)
> 	at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValue(AbstractEntityPersister.java:3600)
> 	at org.hibernate.engine.StatefulPersistenceContext.isFoundInParent(StatefulPersistenceContext.java:1186)
> 	at org.hibernate.engine.StatefulPersistenceContext.getOwnerId(StatefulPersistenceContext.java:1113)
> 	at org.hibernate.property.BackrefPropertyAccessor$BackrefGetter.getForInsert(BackrefPropertyAccessor.java:139)
> 	at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValuesToInsert(AbstractEntityTuplizer.java:287)
> 	at org.hibernate.tuple.entity.PojoEntityTuplizer.getPropertyValuesToInsert(PojoEntityTuplizer.java:256)
> 	at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValuesToInsert(AbstractEntityPersister.java:3677)
> 	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290)
> 	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
> 	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
> 	at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
> 	at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
> 	at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:241)
> 	at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:292)
> 	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:240)
> 	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
> 	at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:320)
> 	at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:266)
> 	at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:243)
> 	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
> 	at org.hibernate.engine.Cascade.cascadeComponent(Cascade.java:222)
> 	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:203)
> 	at org.hibernate.engine.Cascade.cascadeComponent(Cascade.java:222)
> 	at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:203)
> 	at org.hibernate.engine.Cascade.cascade(Cascade.java:154)
> 	at org.hibernate.engine.Cascade.cascade(Cascade.java:121)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:380)
> 	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:352)
> 	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:535)
> 	at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
> 	at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:523)
> 	at com.ited.hibernate.impl.DaoHibernateBase.saveOrUpdateEntity(DaoHibernateBase.java:55)
> 	at com.ited.hibernate.impl.DaoHibernateBase.saveOrUpdateEntity(DaoHibernateBase.java:1)
> 	at sun.reflect.GeneratedMethodAccessor18.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
> 	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
> 	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
> 	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
> 	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
> 	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
> 	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
> 	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
> 	at $Proxy12.saveOrUpdateEntity(Unknown Source)
> 	at sun.reflect.GeneratedMethodAccessor18.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at com.ited.lang.proxy.intern.impl.MethodInvokerDefault.invokeMethod(MethodInvokerDefault.java:79)
> 	at com.ited.lang.proxy.intern.impl.MethodInvokerDefault.invoke(MethodInvokerDefault.java:69)
> 	at com.ited.lang.proxy.impl.ProxyMethodDefault.invoke(ProxyMethodDefault.java:369)
> 	at com.ited.lang.proxy.impl.ProxyMethodDefault.invoke(ProxyMethodDefault.java:174)
> 	at com.ited.persist.ProxyMethodDaoHibernate.invoke(ProxyMethodDaoHibernate.java:56)
> 	... 62 more
> Caused by: java.lang.NullPointerException
> 	at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:36)
> 	at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:18)
> 	at java.lang.reflect.Field.get(Field.java:358)
> 	at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:55)
> 	... 126 more
> ---- 
> Sorry for not having a test case, but it occurs under a combination of curcumstances and is a bit complex.
> I do the following:
> Object graph:
> Entity E1 has an association to E2 with a cascade update/delete. E2 is dependent on E1 and should be a Value type object, but I made it a entity for performance reasons to get lazy loading. E1 and E2 share the same String id (UUID).
> E2 has 2 other Value type associations V1 and V2.
> Actions:
> I create a new E1 with E2 and no V1 and V2, and saveOrUpdate this in one transaction to the database.
> Then I create a NEW E2 (with the same Id as the old E1), add V1 and V2 to E2 and saveOrUpdate only E2 and get the exception above.
> BTW: I changed my code now such that E2 can't be replaced by another version with the same ID, which I think is also more "healhty", but I think that still Hibernate should be able to deal with this situation. 
> What happens in the Hibernate code:
> When I saveOrUpdate E2, it will first call StatefulPersistenceContext.addEntry from DefaultSaveOrUpdateEventListener.performUpdate
> The call trace of this call:
> -------------
> 	StatefulPersistenceContext.addEntry(Object, Status, Object[], Object, Serializable, Object, LockMode, boolean, EntityPersister, boolean, boolean) line: 481	
> 	StatefulPersistenceContext.addEntity(Object, Status, Object[], EntityKey, Object, LockMode, boolean, EntityPersister, boolean, boolean) line: 433	
> 	DefaultSaveOrUpdateEventListener.performUpdate(SaveOrUpdateEvent, Object, EntityPersister) line: 330	
> 	DefaultSaveOrUpdateEventListener.entityIsDetached(SaveOrUpdateEvent) line: 246	
> 	DefaultSaveOrUpdateEventListener.performSaveOrUpdate(SaveOrUpdateEvent) line: 112	
> 	DefaultSaveOrUpdateEventListener.onSaveOrUpdate(SaveOrUpdateEvent) line: 93	
> 	SessionImpl.fireSaveOrUpdate(SaveOrUpdateEvent) line: 535	
> 	SessionImpl.saveOrUpdate(String, Object) line: 527	
> 	SessionImpl.saveOrUpdate(Object) line: 523	
> 	DaoHibernateBase.saveOrUpdateEntity(Serializable) line: 55	
> 	DaoHibernateBase.saveOrUpdateEntity(Object) line: 1	
> 	GeneratedMethodAccessor18.invoke(Object, Object[]) line: not available	
> 	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
> 	Method.invoke(Object, Object...) line: 597	
> ------------- 
> Because this entity is already present (because the old Id of E2 was used) in entityEntries it will NOT be added, leaving the old one in the entityEntries (idea: maybe Hibernate should throw an exception in this case... ). 
> Hibernate will then perform cascading updates of V1 and V2. It will then call  StatefulPersistenceContext.getOwnerId and will retrieve the OLD E2 from entityEntries. Because the old E2 has no V1 and V2 it will throw a null pointer exception when using this one to access the field.
> The call trace just before the exception:
> -------------
> Thread [main] (Suspended (breakpoint at line 58 in DirectPropertyAccessor$DirectGetter))	
> 	DirectPropertyAccessor$DirectGetter.get(Object) line: 58	
> 	PojoComponentTuplizer(AbstractComponentTuplizer).getPropertyValue(Object, int) line: 87	
> 	ComponentType.getPropertyValue(Object, int, EntityMode) line: 366	
> 	PojoEntityTuplizer(AbstractEntityTuplizer).getComponentValue(ComponentType, Object, String) line: 335	
> 	PojoEntityTuplizer(AbstractEntityTuplizer).getPropertyValue(Object, String) line: 306	
> 	SingleTableEntityPersister(AbstractEntityPersister).getPropertyValue(Object, String, EntityMode) line: 3600	
> 	StatefulPersistenceContext.isFoundInParent(String, Object, EntityPersister, CollectionPersister, Object) line: 1186	
> 	StatefulPersistenceContext.getOwnerId(String, String, Object, Map) line: 1113	
> 	BackrefPropertyAccessor$BackrefGetter.getForInsert(Object, Map, SessionImplementor) line: 139	
> 	PojoEntityTuplizer(AbstractEntityTuplizer).getPropertyValuesToInsert(Object, Map, SessionImplementor) line: 287	
> 	PojoEntityTuplizer.getPropertyValuesToInsert(Object, Map, SessionImplementor) line: 256	
> 	SingleTableEntityPersister(AbstractEntityPersister).getPropertyValuesToInsert(Object, Map, SessionImplementor) line: 3677	
> 	DefaultSaveOrUpdateEventListener(AbstractSaveEventListener).performSaveOrReplicate(Object, EntityKey, EntityPersister, boolean, Object, EventSource, boolean) line: 290	
> 	DefaultSaveOrUpdateEventListener(AbstractSaveEventListener).performSave(Object, Serializable, EntityPersister, boolean, Object, EventSource, boolean) line: 204	
> 	DefaultSaveOrUpdateEventListener(AbstractSaveEventListener).saveWithGeneratedId(Object, String, Object, EventSource, boolean) line: 144	
> 	DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(SaveOrUpdateEvent) line: 210	
> 	DefaultSaveOrUpdateEventListener.entityIsTransient(SaveOrUpdateEvent) line: 195	
> 	DefaultSaveOrUpdateEventListener.performSaveOrUpdate(SaveOrUpdateEvent) line: 117	
> 	DefaultSaveOrUpdateEventListener.onSaveOrUpdate(SaveOrUpdateEvent) line: 93	
> 	SessionImpl.fireSaveOrUpdate(SaveOrUpdateEvent) line: 535	
> 	SessionImpl.saveOrUpdate(String, Object) line: 527	
> 	CascadingAction$5.cascade(EventSource, Object, String, Object, boolean) line: 241	
> 	Cascade.cascadeToOne(Object, Type, CascadeStyle, Object, boolean) line: 292	
> 	Cascade.cascadeAssociation(Object, Type, CascadeStyle, Object, boolean) line: 240	
> 	Cascade.cascadeProperty(Object, Type, CascadeStyle, Object, boolean) line: 193	
> 	Cascade.cascadeCollectionElements(Object, CollectionType, CascadeStyle, Type, Object, boolean) line: 320	
> 	Cascade.cascadeCollection(Object, CascadeStyle, Object, CollectionType) line: 266	
> 	Cascade.cascadeAssociation(Object, Type, CascadeStyle, Object, boolean) line: 243	
> 	Cascade.cascadeProperty(Object, Type, CascadeStyle, Object, boolean) line: 193	
> 	Cascade.cascadeComponent(Object, AbstractComponentType, Object) line: 222	
> 	Cascade.cascadeProperty(Object, Type, CascadeStyle, Object, boolean) line: 203	
> 	Cascade.cascadeComponent(Object, AbstractComponentType, Object) line: 222	
> 	Cascade.cascadeProperty(Object, Type, CascadeStyle, Object, boolean) line: 203	
> 	Cascade.cascade(EntityPersister, Object, Object) line: 154	
> 	Cascade.cascade(EntityPersister, Object) line: 121	
> 	DefaultSaveOrUpdateEventListener.cascadeOnUpdate(SaveOrUpdateEvent, EntityPersister, Object) line: 380	
> 	DefaultSaveOrUpdateEventListener.performUpdate(SaveOrUpdateEvent, Object, EntityPersister) line: 352	
> 	DefaultSaveOrUpdateEventListener.entityIsDetached(SaveOrUpdateEvent) line: 246	
> 	DefaultSaveOrUpdateEventListener.performSaveOrUpdate(SaveOrUpdateEvent) line: 112	
> 	DefaultSaveOrUpdateEventListener.onSaveOrUpdate(SaveOrUpdateEvent) line: 93	
> 	SessionImpl.fireSaveOrUpdate(SaveOrUpdateEvent) line: 535	
> 	SessionImpl.saveOrUpdate(String, Object) line: 527	
> 	SessionImpl.saveOrUpdate(Object) line: 523	
> 	DaoHibernateBase.saveOrUpdateEntity(Serializable) line: 55	
> 	DaoHibernateBase.saveOrUpdateEntity(Object) line: 1	
> 	GeneratedMethodAccessor18.invoke(Object, Object[]) line: not available	
> 	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
> 	Method.invoke(Object, Object...) line: 597	
> ------------- 
> Hope it contains enough information to deal with it.

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