Пожалуйста, помогите мне настроить Custom LocalSessionFactoryBean

В рамках обновления гибернации я не могу настроить фабрику сеансов. Во время выполнения, в зависимости от системной переменной, мы используем либо схему, либо mock_schema. Мы делали настройку в postProcessConfiguration.

Я не очень понимаю, где подключить код, и не очень понимаю весенний поток при создании фабрики сеансов.

Из спящего режима у меня есть решение.https://vladmihalcea.com/how-to-get-the-entity-mapping-to-database-table-binding-metadata-from-hibernate/#comments

  1. Как иметь более одного Интегратора говорят MetadataExtractorIntegrator и EventListenerIntegrator.
  2. Как настроить в случае CustomLocalSessionFactoryBean (расширяет LocalSessionFactoryBean).
  3. Могу ли я сделать это без переопределения LocalSessionFactoryBean ?
  4. Как получить/изменить getCollectionMappings из конфигурации?

    открытый класс CustomHibernateSessionFactoryBean расширяет org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean {

    @Inject
    private DatabasePlatform dbPlatform;
    
    @Inject
    private ApplicationContext applicationContext;
    
    @Override
    protected SessionFactory newSessionFactory(Configuration config) {
        config.setProperty(DatabasePlatform.HIBERNATE_DIALECT_KEY, this.dbPlatform.getDialectClass().getName());
    
        //Many such event listeners
        config.getEventListeners().setUpdateEventListeners(sortAndConcat(config.getEventListeners().getUpdateEventListeners(),saveOrUpdateEventListeners));
    
        return super.newSessionFactory(config);
    }
    
    @Override
    protected void postProcessConfiguration(Configuration config) {
        super.postProcessConfiguration(config);
    
        if (!DatabasePlatform.INVENTORY_SCHEMA.equals(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA)) {
            logger.info("Overriding inventory schema name to %s", DatabasePlatform.INVENTORY_SCHEMA);
            Iterator<PersistentClass> classIterator = config.getClassMappings();
    
            while (classIterator.hasNext()) {
                PersistentClass persistentClass = classIterator.next();
                replaceSchemaName(persistentClass.getTable());
                Iterator<Join> joinIterator = persistentClass.getJoinIterator();
                while (joinIterator.hasNext()) {
                    replaceSchemaName(joinIterator.next().getTable());
                }
    
                Iterator<org.hibernate.mapping.Collection> collectionIterator = config.getCollectionMappings();
                while (collectionIterator.hasNext()) {
                    replaceSchemaName(collectionIterator.next().getCollectionTable());
                }
            }
        }
    }
    
    private void replaceSchemaName(Table table) {
        if (DatabasePlatform.DEFAULT_INVENTORY_SCHEMA.equals(table.getSchema())) {
            table.setSchema(DatabasePlatform.INVENTORY_SCHEMA);
        }
        if (table.getName().startsWith(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA + ".")) {
            table.setName(table.getName().replaceFirst(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA, DatabasePlatform.INVENTORY_SCHEMA));
        }
    }
    

    }

Новый код, который я пытаюсь использовать для спящего режима 5

@SuppressWarnings("unused")
public class CustomHibernateSessionFactoryBean extends org.springframework.orm.hibernate5.LocalSessionFactoryBean {

    @Inject
    private ApplicationContext applicationContext;

    private static final SystemLogger logger = SystemLogger.getLogger(CustomHibernateSessionFactoryBean.class);

    @Inject
    private DatabasePlatform dbPlatform;

    private AsyncTaskExecutor bootstrapExecutor;

    private EventListenerIntegrator eventListenerIntegrator;

    private final RegionFactory regionFactory;

    private boolean metadataSourcesAccessed;

    private MetadataSources metadataSources;

    public CustomHibernateSessionFactoryBean() {
        // TODO: Check what is the effect of regionFactory not being set
        regionFactory = null;
    }

    CustomHibernateSessionFactoryBean(RegionFactory regionFactory, EventListenerIntegrator eventListenerIntegrator) {
        this.regionFactory = regionFactory;
        this.eventListenerIntegrator = eventListenerIntegrator;
    }

    CustomHibernateSessionFactoryBean(EventListenerIntegrator eventListenerIntegrator) {
        this.regionFactory = null;
        this.eventListenerIntegrator = eventListenerIntegrator;
    }

    @Override
    public void setMetadataSources(MetadataSources metadataSources) {
        Assert.notNull(metadataSources, "MetadataSources must not be null");
        this.metadataSourcesAccessed = true;
        this.metadataSources = metadataSources;
    }

    @Override
    public MetadataSources getMetadataSources() {
        this.metadataSourcesAccessed = true;
        if (this.metadataSources == null) {
            BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
            ResourcePatternResolver resourcePatternResolver = (ResourcePatternResolver) getResourceLoader();
            if (resourcePatternResolver != null) {
                builder = builder.applyClassLoader(resourcePatternResolver.getClassLoader()).applyIntegrator(eventListenerIntegrator);
            }
            this.metadataSources = new MetadataSources(builder.build());
        }
        return this.metadataSources;
    }

    @Override
    protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) {

        getConfiguration().setProperty(DatabasePlatform.HIBERNATE_DIALECT_KEY, this.dbPlatform.getDialectClass().getName());
        if (!DatabasePlatform.INVENTORY_SCHEMA.equals(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA)) {
            logger.info("Overriding inventory schema name to %s", DatabasePlatform.INVENTORY_SCHEMA);
            Metadata metadata = getMetadataSources().getMetadataBuilder().build();
            Collection<PersistentClass> entityBindings = metadata.getEntityBindings();

            for (Iterator<PersistentClass> iterator = entityBindings.iterator(); iterator.hasNext();) {
                PersistentClass persistentClass = iterator.next();
                replaceSchemaName(persistentClass.getTable());
                @SuppressWarnings("unchecked")
                Iterator<Join> joinIterator = persistentClass.getJoinIterator();
                while (joinIterator.hasNext()) {
                    replaceSchemaName(joinIterator.next().getTable());
                }
            }
        }
        return (this.bootstrapExecutor != null ? sfb.buildSessionFactory(this.bootstrapExecutor) : sfb.buildSessionFactory());

    }

    private void replaceSchemaName(Table table) {
        if (DatabasePlatform.DEFAULT_INVENTORY_SCHEMA.equals(table.getSchema())) {
            table.setSchema(DatabasePlatform.INVENTORY_SCHEMA);
        }
        if (table.getName().startsWith(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA + ".")) {
            table.setName(table.getName().replaceFirst(DatabasePlatform.DEFAULT_INVENTORY_SCHEMA, DatabasePlatform.INVENTORY_SCHEMA));
        }
    }
}

Зачем мне настраивать localsessionFactoryBean?

I have 2 need for using SessionFactoryBean
    1. Normal application
    2. Dbtest

In normal application, schema1 is populated by other process
In Dbtest, i need to use mock_schema1 instead of schema1 so that we will not rewrite data populated by other application.

@ Table(name = “cluster”, schema = “schema1”)
@ SecondaryTable(name = “Cluster”, schema = “schema2”, pkJoinColumns = @ PrimaryKeyJoinColumn(name = “clusterId”, referencedColumnName = “objid”))
@ org.hibernate.annotations.Table(appliesTo = “Cluster”, optional = false)
@ Entity
@ OptimisticLocking(type = OptimisticLockType.DIRTY)
@ DynamicUpdate
public class Cluster implements Serializable {

} Но если вы видите, что мое определение сущности использует «schema1» во время выполнения, если я запускаю Dbtest, я хочу, чтобы сущность использовала «mock_schema1» вместо «schema1».

================================================== ====================== Это ответ на вопрос М. Дейнум:

В моем тесте установка hibernate.default_schema не будет служить моей цели.

Бывший. как часть dbtest, если я установлю объект кластера и сохраню его, он попытается заполнить mock_schema2 и schema1. Вместо этого я хочу schema2 и mock_schema1.

Если вы обновляете спящий режим, пытаясь настроить его с помощью класса спящего режима 3 из Spring, это не сработает. Кроме того, почему так сложно? Почему бы не создать 2 конфига на основе системного свойства? Или, если вы используете java-config, просто выполните проверку в java и установите схему по умолчанию вместо того, чтобы пытаться переконфигурировать спящий режим.

M. Deinum 03.02.2019 20:12

Я обновил описание способом инициализации hibernate5. Я не могу изменить имя схемы вторичной таблицы для Dbtest. есть ли для этого свойство гибернации? Мне также нужно инициализировать eventListenerIntegrator.

sandeep kamath 04.02.2019 11:31

Опять же, почему так сложно? Почему бы просто не добавить if в конфигурацию LocalSessioNFasctoryBean, которая установит схему по умолчанию.

M. Deinum 04.02.2019 11:32

Извините, я отредактировал предыдущий комментарий к тому времени, когда вы ответили. Мне нужно изменить дополнительную таблицу, а не основную таблицу. Схема по умолчанию Hope изменяет только схему основной таблицы.

sandeep kamath 04.02.2019 11:36

Я понятия не имею, что вы имеете в виду под первичной и вторичной таблицей... Для меня то, что вы создали, меняет схему таблиц. И согласно вашему описанию вы хотите использовать схему x или y на основе свойства. Тогда это решение кажется слишком сложным.

M. Deinum 04.02.2019 11:40

Мы сопоставляем одну сущность более чем с одной таблицей. Основная таблица управляется нашим приложением. Дополнительная таблица управляется другим приложением. мы обычно читаем необходимые свойства и из вторичной таблицы. @ Table(name = «cluster», schema = «schema1») @ SecondaryTable(name = «Cluster», schema = «schema2», pkJoinColumns = @ PrimaryKeyJoinColumn(name = «clusterId», referencedColumnName = «objid»)) @ org .hibernate.annotations.Table(appliesTo = «Cluster», необязательно = false) @ Открытый класс Entity Cluster реализует Serializable { }

sandeep kamath 04.02.2019 11:51

Пожалуйста, не добавляйте дополнительный код в качестве комментариев, это совершенно нечитаемо. Вместо этого отредактируйте свой вопрос с дополнительной информацией. Эта информация кажется важной, поскольку в настоящее время ее нет в вашем вопросе. Что касается интеграторов, они должны быть обнаружены автоматически, поэтому похоже, что вы пытаетесь делать то, чего не должны делать. Я подозреваю, что вам лучше использовать выделенный orm.xml, чтобы переопределить схему для этих таблиц. Затем загружайте этот orm.xml только при наличии системного свойства.

M. Deinum 04.02.2019 11:54

Давайте продолжить обсуждение в чате.

sandeep kamath 05.02.2019 06:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
8
389
0

Другие вопросы по теме