Vicky
Vicky

Reputation: 11

SpringOrm-Hibernate 4 to 5 migration issue - need to mutate metadata before building sessionFactory

I'm trying to upgrade from Hibernate 4.3.11 to 5.4.x with Spring-Orm 4.3.29. As part of the upgrade, I need to migrate existing custom logic that is dependent on NamedSQLQueries retrieved from Hibernate Configuration class. This custom logic mutates the NamedSQLQueries and updates back to the original Map before building the sessionFactory. In the new version (5.x) - I modified the bootstrapping as per the new documentation and able to build the metadata but not able to mutate the namedNativeQueries (per documentation metadata is immutable). Is there a way to mutate the metadata before building the sessionFactory.

Current code -

public class CustomFactoryBean extends LocalSessionFactoryBean {
...

    @Override
    protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder localSessionFactoryBuilder) {
      localSessionFactoryBuilder.buildMappings(); //deprecated in 5.x
      mutateNamedSQLQueries(localSessionFactoryBuilder.getNamedSQLQueries()); //mutates NamedSQLQueries and updates back to the Map (Map<String, NamedSQLQueryDefinition>) AND localSessionFactoryBuilder.getNamedSQLQueries() returns nothing in 5.x (deprecated)
      localSessionFactoryBuilder.buildSessionFactory();
    }

}

New Code -

    @Override
    protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder localSessionFactoryBuilder) {

            final BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder()
                    .enableAutoClose()
                    .applyIntegrator(MetadataExtractorIntegrator.INSTANCE) //MetadataExtractorIntegrator class is based on the 2nd link below
                    .build();
            
            final StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder(bootstrapServiceRegistry)
                    .applySettings(localSessionFactoryBuilder.getProperties())
                    .build();
            
            MetadataSources metadataSources = new MetadataSources(serviceRegistry);
            metadataSources.addAnnotatedClass(TestEntity.class);
            
            Metadata metadata = metadataSources.buildMetadata();
            
            List<NamedSQLQueryDefinition> namedSQLQueryDefinitions = new ArrayList<>(metadata.getNamedNativeQueryDefinitions());
            mutateNamedNativeQueries(namedSQLQueryDefinitions); //not able to mutate namedSQLQueryDefinitions since metadata is immutable

            return metadata.buildSessionFactory();

    }

Per this link - https://hibernate.atlassian.net/browse/HHH-12089, looks like the right way to mutate metadata before building it is to use MetadataContributor but I don't see an example or any mention in the official documentation where and how to plugin the custom MetadataContributor.

References - Building the sessionFactory in Hibernate 5 https://docs.jboss.org/hibernate/stable/orm/userguide/html_single/Hibernate_User_Guide.html#bootstrap-native-SessionFactory

To read the metadata once the sessionFactory is built https://vladmihalcea.com/how-to-get-access-to-database-table-metadata-with-hibernate-5/

Any help on this would be much appreciated.

Upvotes: 1

Views: 832

Answers (1)

Christian Beikov
Christian Beikov

Reputation: 16452

In a MetadataContributor you can remove entries from InFlightMetadataCollector#getNamedQueryDefinitions and re-add them after doing your changes.

Upvotes: 0

Related Questions