Uploaded image for project: 'Hibernate ORM'
  1. HHH-13110

@PreUpdate method on a Embeddable null on the parent caused NullPointerException

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5.3.6
    • Fix Version/s: 5.4.0
    • Component/s: hibernate-core
    • Labels:
      None
    • Environment:
      Developpement
    • Bug Testcase Reminder (view):

      Bug reports should generally be accompanied by a test case!

    • Last commented by a user?:
      true
    • Sprint:

      Description

      I have a class A with a relation to a BEmbeddable. The BEmbeddable have a @PreUpdate method.

      When creating the entity A with BEmbeddable null, then save A, it tries to call the @PreUpdate on B which is null.

      Basically the problem is that we try to call the method PreUpdate on a null element of B.

      Stack trace of nullpointer in Debug:

      invoke:62, NativeMethodAccessorImpl {sun.reflect}
      invoke:43, DelegatingMethodAccessorImpl {sun.reflect}
      invoke:498, Method {java.lang.reflect}
      performCallback:35, EmbeddableCallback {org.hibernate.jpa.event.internal}
      callback:97, CallbackRegistryImpl {org.hibernate.jpa.event.internal}
      preCreate:57, CallbackRegistryImpl {org.hibernate.jpa.event.internal}
      saveWithGeneratedId:116, AbstractSaveEventListener {org.hibernate.event.internal}
      entityIsTransient:192, DefaultPersistEventListener {org.hibernate.event.internal}
      onPersist:135, DefaultPersistEventListener {org.hibernate.event.internal}
      onPersist:62, DefaultPersistEventListener {org.hibernate.event.internal}
      firePersist:800, SessionImpl {org.hibernate.internal}
      persist:785, SessionImpl {org.hibernate.internal}
      

      Line 62 is `invoke0(method, obj, args)` with method = @PreUpdate method and obj is null.

      Maybe a null check is missing in `performCallback:35, EmbeddableCallback org.hibernate.jpa.event.internal`

      	@Override
      	public boolean performCallback(Object entity) {
      		try {
      			Object embeddable = embeddableGetter.get( entity ); // <--- embeddable is null
      			callbackMethod.invoke( embeddable ); //<-- missing at least null check here?
      			return true;
      		}
      		catch (InvocationTargetException e) {
      			//keep runtime exceptions as is
      			if ( e.getTargetException() instanceof RuntimeException ) {
      				throw (RuntimeException) e.getTargetException();
      			}
      			else {
      				throw new RuntimeException( e.getTargetException() );
      			}
      		}
      		catch (Exception e) {
      			throw new RuntimeException( e );
      		}
      	}
      

      Printed stack trace:

      java.lang.RuntimeException: java.lang.NullPointerException
      
      	at org.hibernate.jpa.event.internal.EmbeddableCallback.performCallback(EmbeddableCallback.java:48)
      	at org.hibernate.jpa.event.internal.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:97)
      	at org.hibernate.jpa.event.internal.CallbackRegistryImpl.preCreate(CallbackRegistryImpl.java:57)
      	at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:116)
      	at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:192)
      	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
      	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:62)
      	at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:800)
      	at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:785)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:301)
      	at com.sun.proxy.$Proxy113.persist(Unknown Source)
      	at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:508)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:515)
      	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:500)
      	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:477)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
      	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
      	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      	at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
      	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
      	at com.sun.proxy.$Proxy152.save(Unknown Source)
      

        Attachments

          Activity

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: