Make Hibernate Search be compatible with Envers

Description

Expected behavior

I would like to mix hibernate search and envers together. The main goal would be to be able to audit my entity and to have a searchable projection of it using elasticsearch. I do not want to have a representation in elasticsearch of _aud tables and DefaultRevisionEntity.

Current behavior

I made a Quarkus POC to reproduce the current behavior.

The application fails to start due to an exception thrown at startup:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 01:03:18,352 ERROR [io.qua.dev.DevModeMain] Failed to start quarkus: java.lang.ExceptionInInitializerError at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at io.quarkus.runner.RuntimeRunner.run(RuntimeRunner.java:126) at io.quarkus.dev.DevModeMain.doStart(DevModeMain.java:180) at io.quarkus.dev.DevModeMain.start(DevModeMain.java:94) at io.quarkus.dev.DevModeMain.main(DevModeMain.java:66) Caused by: java.lang.RuntimeException: Failed to start quarkus at io.quarkus.runner.ApplicationImpl1.<clinit>(ApplicationImpl1.zig:245) ... 9 more Caused by: org.hibernate.MappingException: component class not found: null at org.hibernate.mapping.Component.getComponentClass(Component.java:177) at org.hibernate.search.mapper.orm.model.impl.HibernateOrmBootstrapIntrospector.collectEmbeddedTypesRecursively(HibernateOrmBootstrapIntrospector.java:105) at org.hibernate.search.mapper.orm.model.impl.HibernateOrmBootstrapIntrospector.create(HibernateOrmBootstrapIntrospector.java:63) at org.hibernate.search.mapper.orm.mapping.impl.HibernateOrmMappingInitiator.create(HibernateOrmMappingInitiator.java:57) at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.doBootFirstPhase(HibernateOrmIntegrationBooterImpl.java:189) at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.preBoot(HibernateOrmIntegrationBooterImpl.java:95) at io.quarkus.hibernate.search.elasticsearch.runtime.HibernateSearchElasticsearchRecorder$HibernateSearchIntegrationListener.onMetadataInitialized(HibernateSearchElasticsearchRecorder.java:82) at io.quarkus.hibernate.orm.runtime.integration.HibernateOrmIntegrations.onMetadataInitialized(HibernateOrmIntegrations.java:29) at io.quarkus.hibernate.orm.runtime.boot.FastBootMetadataBuilder.build(FastBootMetadataBuilder.java:327) at io.quarkus.hibernate.orm.runtime.PersistenceUnitsHolder.createMetadata(PersistenceUnitsHolder.java:111) at io.quarkus.hibernate.orm.runtime.PersistenceUnitsHolder.constructMetadataAdvance(PersistenceUnitsHolder.java:84) at io.quarkus.hibernate.orm.runtime.PersistenceUnitsHolder.initializeJpa(PersistenceUnitsHolder.java:47) at io.quarkus.hibernate.orm.runtime.HibernateOrmRecorder$4.created(HibernateOrmRecorder.java:70) at io.quarkus.arc.runtime.ArcRecorder.initBeanContainer(ArcRecorder.java:92) at io.quarkus.deployment.steps.ArcProcessor$generateResources12.deploy_0(ArcProcessor$generateResources12.zig:364) at io.quarkus.deployment.steps.ArcProcessor$generateResources12.deploy(ArcProcessor$generateResources12.zig:36) at io.quarkus.runner.ApplicationImpl1.<clinit>(ApplicationImpl1.zig:231) ... 9 more Caused by: org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [null] at io.quarkus.hibernate.orm.runtime.service.FlatClassLoaderService.classForName(FlatClassLoaderService.java:39) at org.hibernate.mapping.Component.getComponentClass(Component.java:174) ... 25 more Caused by: java.lang.NullPointerException at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at io.quarkus.hibernate.orm.runtime.service.FlatClassLoaderService.classForName(FlatClassLoaderService.java:37) ... 26 more

To Reproduce

Steps to reproduce the behavior:

1. git clone https://github.com/dcdh/poc-quarkus-persistence.git
2. checkout branch search_with_auditing
3. run the application using the script run_dev.sh

Additional information

The exception occurs because the auditable table is not associated with a JPA entity.

The impacted code is this one from the class HibernateOrmBootstrapIntrospector :

1 2 3 4 for ( PersistentClass persistentClass : persistentClasses ) { collectEmbeddedTypesRecursively( typeMetadata, persistentClass.getIdentifier() ); collectEmbeddedTypesRecursively( typeMetadata, persistentClass.getPropertyIterator() ); }

The auditable tabe is considered as a persistentClasses and when the code will try to collect all embeded type recursively an exception will be thrown and the application will fail.

I notice that for an audited table the className property is null. Maybe that it could be a solution to filter and reject all table persistentClasses having a null className ? and add a special case (or not) regarding the DefaultRevisionEntity but it will introduce a high coupling with Envers...

Quarkus opened issue:

 

Regards,

Damien

Environment

hibernate-search-mapper-orm

Status

Assignee

Damien Clement d'Huart

Reporter

Damien Clement d'Huart

Labels

None

Suitable for new contributors

None

Feedback Requested

None

Fix versions

Affects versions

6.0.0.Alpha7

Priority

Major
Configure