Javers ENTITY_INSTANCE_WITH_NULL_ID when using 2 d

2019-07-13 17:40发布

问题:

I have this exception "ENTITY_INSTANCE_WITH_NULL_ID" when I store data in Postgres (using JPA Lazy Load) and I store javers in MongoDB

Spring Boot: 1.4.0.RELEASE

Sprig Data JPA: 1.4.0.RELEASE

Javers: 2.3.0

I debugged and saw that ID is null if object is a lazy object: org.javers.core.metamodel.type.EntityType:88 "Object cdoId = getIdProperty().get(instance);"

回答1:

When you commit an object to JaVers, its previous version is loaded from JaversRepository and compared with the current version (that version you have just passed to commit() method). In this case JaVers finds the previous version using GlobalId query so TypeName + entity ID. That's why ID can't be null for Entities.

There are two possibilities:

  1. If null ID is normal in this class (according to your domain model) you should map it as ValueObject in JaVers.
  2. If you are using Hibernate, there is common problem with lazy loading proxies. For certain queries, Hibernate doesn't return your real domain objects but dynamic proxy objects which are essentially empty (hence null ID). This technique maybe looks smart but makes your objects garbage until they are initialized by Hibernate. JaVers provides HibernateUnproxyObjectAccessHook which does the cleaning: initializing and un-proxying of your domain objects.

    JaversBuilder.javers().withObjectAccessHook( new HibernateUnproxyObjectAccessHook()).build()

This hook is enabled by default in javers-spring-boot-starter-sql but not in javers-spring-boot-starter-mongo. If you are using Mongo starter, create a JaVers bean on your own, with the hook enabled, see JaversMongoAutoConfiguration.