[hibernate-issues] [Hibernate-JIRA] Created: (HHH-6808) Versionning problem in case of autoFlush required inside an "onSave" interceptor

Romain Fromi (JIRA) noreply at atlassian.com
Mon Nov 7 09:19:22 EST 2011


Versionning problem in case of autoFlush required inside an "onSave" interceptor
--------------------------------------------------------------------------------

                 Key: HHH-6808
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6808
             Project: Hibernate Core
          Issue Type: Bug
          Components: entity-manager
    Affects Versions: 3.5.6
         Environment: Hibernate 3.5.6, Oracle
            Reporter: Romain Fromi


I have an interceptor "onSave" for an Entity.
I try to make a query with hibernate inside this onSave.
The following exception is thrown :

java.lang.NullPointerException
	at org.hibernate.type.IntegerType.next(IntegerType.java:82)
	at org.hibernate.engine.Versioning.increment(Versioning.java:131)
	at org.hibernate.event.def.DefaultFlushEntityEventListener.getNextVersion(DefaultFlushEntityEventListener.java:406)
	at org.hibernate.event.def.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:296)
	at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:155)
	at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219)
	at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99)
	at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:58)
	at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1175)
	at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1699)
	at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
	at org.springframework.orm.hibernate3.HibernateTemplate$36.doInHibernate(HibernateTemplate.java:1056)
	at org.springframework.orm.hibernate3.HibernateTemplate$36.doInHibernate(HibernateTemplate.java:1)
	at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
	at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
...

As you can see, my query triggers an auto flush, because I try to read some objects related to the object currently saved (I cannot access these related objects another way, some relations are not bidirectionnal).
During this auto flush, I have a null pointer inside Versioning.increment because the EntityEntry has a null version, whereas my entity has a version.
I think that the version inside my own entity is not already reported inside the EntityEntry - the proof is in the stack trace before the onSave call:

...
	at org.hibernate.event.def.AbstractSaveEventListener.substituteValuesIfNecessary(AbstractSaveEventListener.java:414)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:293)
	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:677)
...

As you can see, AbstractSaveEventListener.substituteValuesIfNecessary calls my method. But this method also process versionning :

  398   	/**
  399   	 * Perform any property value substitution that is necessary
  400   	 * (interceptor callback, version initialization...)
  401   	 *
  402   	 * @param entity The entity
  403   	 * @param id The entity identifier
  404   	 * @param values The snapshot entity state
  405   	 * @param persister The entity persister
  406   	 * @param source The originating session
  407   	 *
  408   	 * @return True if the snapshot state changed such that
  409   	 * reinjection of the values into the entity is required.
  410   	 */
  411   	protected boolean substituteValuesIfNecessary(
  412   			Object entity,
  413   			Serializable id,
  414   			Object[] values,
  415   			EntityPersister persister,
  416   			SessionImplementor source) {
  417   		boolean substitute = source.getInterceptor().onSave(
  418   				entity,
  419   				id,
  420   				values,
  421   				persister.getPropertyNames(),
  422   				persister.getPropertyTypes()
  423   		);
  424   
  425   		//keep the existing version number in the case of replicate!
  426   		if ( persister.isVersioned() ) {
  427   			substitute = Versioning.seedVersion(
  428   					values,
  429   					persister.getVersionProperty(),
  430   					persister.getVersionType(),
  431   					source
  432   			) || substitute;
  433   		}
  434   		return substitute;
  435   	}

"Versioning.seedVersion" is called after "source.getInterceptor().onSave"

Maybe the version should have already been reported inside the EntityEntry when calling onSave ?

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list