#java #hibernate #sessionfactory #hibernate-5.x #spring-orm
#java #спящий режим #sessionfactory #спящий режим-5.x #весна-orm
Вопрос:
Я пытаюсь перейти с режима гибернации 4.3.11 на 5.4.x с помощью Spring-Orm 4.3.29. В рамках обновления мне нужно перенести существующую пользовательскую логику, которая зависит от NamedSQLQueries, полученных из класса конфигурации Hibernate. Эта пользовательская логика изменяет NamedSQLQueries и обновляется до исходной карты перед созданием SessionFactory. В новой версии (5.x) — я изменил начальную загрузку в соответствии с новой документацией и смог создать метаданные, но не смог изменить namedNativeQueries (метаданные документации неизменяемы). Есть ли способ изменить метаданные перед созданием SessionFactory.
Текущий код —
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();
}
}
Новый Код —
@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();
}
По этой ссылке — https://hibernate.atlassian.net/browse/HHH-12089 , похоже, что правильный способ изменить метаданные перед их созданием — использовать MetadataContributor, но я не вижу примера или какого-либо упоминания в официальной документации, где и как подключить пользовательский MetadataContributor.
Ссылки — Создание SessionFactory в Hibernate 5
https://docs.jboss.org/hibernate/stable/orm/userguide/html_single/Hibernate_User_Guide.html#bootstrap-native-SessionFactory
Для чтения метаданных после создания SessionFactory
https://vladmihalcea.com/how-to-get-access-to-database-table-metadata-with-hibernate-5 /
Любая помощь по этому вопросу будет высоко оценена.
Ответ №1:
В a MetadataContributor
вы можете удалять записи InFlightMetadataCollector#getNamedQueryDefinitions
и повторно добавлять их после внесения изменений.
Комментарии:
1. Я создал CustomContributor, как показано ниже, но я не вижу способа добавить участника в процесс начальной загрузки. общедоступный класс CustomMetadataContributor реализует MetadataContributor { @Override public void contribute(InFlightMetadataCollector metadataCollector, IndexView jandexIndex) { Коллекция<NamedSQLQueryDefinition> namedNativeQueryDefinitions = metadataCollector.getNamedNativeQueryDefinitions(); mutateNamedSQLQueries(namedNativeQueryDefinitions); } частная пустота mutateNamedSQLQueries(коллекция<NamedSQLQueryDefinition> namedNativeQueryDefinitions) { //мутировать здесь } }
2. Повторите именованный собственный запрос и удалите элемент, который вы хотите заменить. После этого вызовите метод addNamedNativeQuery
3. Я повторил и изменил требуемый элемент и добавил его обратно как новый элемент, используя addNamedNativeQuery, но эта логика не вызывается в процессе начальной загрузки. Нужно ли мне добавлять этот CustomContributor в StandardServiceRegistry или MetadataSources или что-то еще, чтобы эта логика вызывалась?
4. code — NamedSQLQueryDefinition namedNativeQueryDefinition = metadataCollector.getNamedNativeQueryDefinition(«TestEntity.namedNativeQuery»);namedNativeQueryDefinition.getQueryString().replace(«TEST» , «TEST_TEMP»);metadataCollector.addNamedNativeQuery(новый NamedSQLQueryDefinitionBuilder().setName(namedNativeQueryDefinition.getName()).setFetchSize(namedNativeQueryDefinition.getFetchSize()).createNamedQueryDefinition());
5. Привет, Крис, метод переопределения в пользовательском контрибьюторе вызывается после добавления имени класса пользовательского контрибьютора в файл org.hibernate.boot.spi.MetadataContributor в каталоге resources / META-INF / services, но проблема в том, что ни один из компонентов Spring не доступен в этом пользовательском контрибьюторе, что затрудняет мой процесс мутации. Я пропустил ввод участника в неправильном месте? Не могли бы вы предложить?