building Metadata multiple times makes EnversService throw an UnsupportedOperationException
Description
Activity

zyro November 14, 2017 at 3:44 PM
agreed. thx.

Chris Cranford November 14, 2017 at 3:42 PM
is that the recommended approach, i.e. should re-building the
Metadata
be avoided?
The main issue with executing the build process again is that you're effectively doing double work. This causes Hibernate to parse annotations, hbm xml files, and for Envers to rebuild and create all the necessary audit hbm xml configurations again. Based on your domain model size, this could introduce some overhead in memory and performance.
or is there any specific reason why envers does not allow it?
The primary reason is that the current EnversService
is registered as a global-service in the StandardServiceRegistry
. It maintains a bit of state about the audited entities it generates by interpreting the Hibernate Metadata
and so rebuilding the Metadata
would override the service's global state; hence why the guard exists to avoid this potential pitfall.
With that said, I would say you have 2 alternatives:
org.hibernate.integrator.spi.Integrator
org.hibernate.boot.spi.MetadataContributor
The Integrator
contract is ideal if you're needing a fully built Metadata
instance that has had all second passes, other MetadataContributor
contributions, and Envers contributions added. But if you're looking for a step in the build process to perhaps mutate the Metadata
prior to second passes and Envers contributions, then a MetadataContributor
is a great spot.
With that I am going to close this issue as I think one of the above alternatives make more sense logically.

zyro November 13, 2017 at 4:12 PM
we are using a framework (Grails/GORM) that takes care of the hibernate initialization and a few plugins which re-build the Metadata
(for the existing SessionFactory
) at runtime, after the initial bootstrapping already happened, in order to allow to introspect the Metadata
.
this works fine as long as envers is not in use because of this guard: https://github.com/hibernate/hibernate-orm/blob/5.2.12/hibernate-envers/src/main/java/org/hibernate/envers/boot/internal/EnversServiceImpl.java#L108
i also read https://vladmihalcea.com/2017/08/24/how-to-get-the-entity-mapping-to-database-table-binding-metadata-from-hibernate which suggests using an Integrator
to capture and expose the built Metadata
.
is that the recommended approach, i.e. should re-building the Metadata
be avoided?
or is there any specific reason why envers does not allow it?
thanks for your feedback!

Chris Cranford November 13, 2017 at 3:30 PM
Is there a particular reason why you need to build the MetadataSources
with an existing ServiceRegistry
that is associated with a fully functional SessionFactory
?
I would have expected that if you needed to do something like this that you would have built a new ServiceRegistry
and used it like all the other tests in `hibernate-core`:
building
MetaData
a second time for an existingServiceRegistry
, e.g. vianew MetadataSources(myServiceRegistry).getMetadataBuilder().build()
fails with:
test case app based on envers-5 template: https://github.com/zyro23/hhh-12089
thanks, zyro