'Javers - PROPERTY_NOT_FOUND: Property 'id' not found in class 'EntityName$HibernateProxy$Azi44O4n'

I am trying to audit my entities using Javers (6.5.2). When I am doing .save() or .saveAndFlush() operation in Spring Boot (2.5.5), I randomly get the following exception:

org.javers.common.exception.JaversException: PROPERTY_NOT_FOUND: Property 'id' not found in class package.to.entity.EntityName$HibernateProxy$Azi44O4n'. If the name is correct - check annotations. Properties with @DiffIgnore or @Transient are not visible for JaVers.
    at org.javers.core.metamodel.type.ManagedClass.getProperty(ManagedClass.java:83)
    at org.javers.core.metamodel.type.ManagedClass.lambda$getProperties$1(ManagedClass.java:93)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
    at org.javers.core.metamodel.type.ManagedClass.getProperties(ManagedClass.java:93)
    at org.javers.core.metamodel.type.EntityType.spawn(EntityType.java:60)
    at org.javers.core.metamodel.type.EntityType.spawn(EntityType.java:44)
    at org.javers.core.metamodel.type.TypeFactory.spawnFromPrototype(TypeFactory.java:145)
    at org.javers.core.metamodel.type.TypeFactory.infer(TypeFactory.java:98)
    at org.javers.core.metamodel.type.TypeMapper.lambda$getJaversType$0(TypeMapper.java:99)
    at org.javers.core.metamodel.type.TypeMapperEngine.computeIfAbsent(TypeMapperEngine.java:110)
    at org.javers.core.metamodel.type.TypeMapper.getJaversType(TypeMapper.java:99)
    at org.javers.core.JaversCore.assertJaversTypeNotValueTypeOrPrimitiveType(JaversCore.java:98)
    at org.javers.core.JaversCore.commit(JaversCore.java:85)
    at org.javers.spring.transactions.JaversTransactionalDecorator.commit(JaversTransactionalDecorator.java:68)
    at org.javers.spring.jpa.JaversTransactionalJpaDecorator.commit(JaversTransactionalJpaDecorator.java:50)
    at org.javers.spring.jpa.JaversTransactionalJpaDecorator$$FastClassBySpringCGLIB$$8b0feaeb.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
    at org.javers.spring.jpa.JaversTransactionalJpaDecorator$$EnhancerBySpringCGLIB$$3ff29c58.commit(<generated>)
    at org.javers.spring.auditable.aspect.JaversCommitAdvice.commitObject(JaversCommitAdvice.java:93)
    at java.base/java.util.Arrays$ArrayList.forEach(Arrays.java:4390)
    at java.base/java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1085)
    at org.javers.spring.auditable.aspect.springdata.AbstractSpringAuditableRepositoryAspect.lambda$onSave$0(AbstractSpringAuditableRepositoryAspect.java:28)
    at java.base/java.util.Optional.ifPresent(Optional.java:183)
    at org.javers.spring.auditable.aspect.springdata.AbstractSpringAuditableRepositoryAspect.onSave(AbstractSpringAuditableRepositoryAspect.java:27)
    at org.javers.spring.auditable.aspect.springdatajpa.JaversSpringDataJpaAuditableRepositoryAspect.onSaveAndFlushExecuted(JaversSpringDataJpaAuditableRepositoryAspect.java:51)
    at jdk.internal.reflect.GeneratedMethodAccessor541.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:617)
    at org.springframework.aop.aspectj.AspectJAfterReturningAdvice.afterReturning(AspectJAfterReturningAdvice.java:66)
    at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:58)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
    at com.sun.proxy.$Proxy313.saveAndFlush(Unknown Source)
    at package.to.entity.EntityService.add(EntityName.java:139)
    at package.to.entity.EntityService$$FastClassBySpringCGLIB$$4a066350.invoke(<generated>)...

This happens randomly (at least on my local backend). Yesterday, at first, everything was working fine, then after application restart, I just couldn't save my entity (I am not aware of changing anything important in my code). Today (still not aware of changing anything), it just suddenly started working locally and I can not simulate this problem anymore. I could only simulate in on environment from frontend deployed branch, so I could get at least exception from OpenShift console.

How id attribute in entity is defined:

  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

How I save entity:

  public EntityName add(Dto dto) {
    EntityName entity = dto.mapToEntity();

    entity = repository.saveAndFlush(entity);
    repository.refresh(entity); // In debug it wasn't even able to make it here

    return entity;
  }

I have @TypeName in my entity defined.

Javers configuration:

@Bean(name = "JaversFromStarter")
  public Javers javers(
    JaversSqlRepository sqlRepository, PlatformTransactionManager txManager,
    JaversSqlProperties sqlProperties
  ) {
    return TransactionalJpaJaversBuilder.javers()
      .withTxManager(txManager)
      .registerJaversRepository(sqlRepository)
      .withObjectAccessHook(sqlProperties.createObjectAccessHookInstance())
      .withProperties(sqlProperties)
      .registerValueTypeAdapter(new JsonNodeTypeAdapter())
      .registerValueTypeAdapter(new InstantTypeAdapter())
      .build();
  }

When I checked JaversSqlProperties, it is using HibernateUnproxyObjectAccessHook so I think it should be able to unproxy the entity properly before auditing it.

Javers configuration in application.yml:

javers:
  mappingStyle: FIELD
  algorithm: SIMPLE
  commitIdGenerator: synchronized_sequence
  prettyPrint: true
  typeSafeValues: false
  newObjectSnapshot: false
  auditableAspectEnabled: true
  springDataAuditableRepositoryAspectEnabled: true
  sqlSchemaManagementEnabled: true
  sqlGlobalIdCacheDisabled: false
  prettyPrintDateFormats:
    localDateTime: "dd MMM yyyy, HH:mm:ss"
    zonedDateTime: "dd MMM yyyy, HH:mm:ssZ"
    localDate: "dd MMM yyyy"
    localTime: "HH:mm:ss"

PS: This entity has a reference to other audited entity (which is saved before this one).

Does anyone please have any idea, what could be wrong?



Solution 1:[1]

As a rule of thumb, you should newer treat Hibernate proxies as your Entities. Do you use HibernateUnproxyHook? I recommend using the javers' starter. It sets up all javers' beans (including this hook).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Bartek Walacik