Hibernate plusieurs connexions changeant dynamicment

Je sais qu’il existe des questions similaires sur ce scénario, mais aucune d’entre elles n’a correspondu à mon cas et j’aimerai disposer d’une solution sans impact sur les performances. Je dois faire plusieurs connexions à différentes bases de données (toutes postgresql) et le problème est que les bases de données peuvent être nombreuses car elles sont continuellement créées.

Pour le moment, je n’ai qu’une seule firebase database connue qui sera utilisée pour stocker les chaînes de connexion des autres bases de données. Ces bases de données peuvent être 1, 2, 5, 10 ou N. La partie la plus délicate est que, de mon côté, je ne saurai jamais combien elles seront, ni leur emplacement et leurs informations d’identification (toutes stockées dans ma firebase database centrale). Le cas d’utilisation fonctionne de telle manière que pour effectuer une opération sur l’une de ces bases de données, je dois d’abord extraire de la firebase database centrale l’emplacement de la firebase database dont nous avons besoin, puis effectuer l’opération.

Pour l’instant, j’ai pu effectuer l’opération en chantant SessionFactory, mais l’opération est trop lente, même pour une simple sélection / mise à jour, et je crains que lorsqu’une pluralité de requêtes est émise, nous risquions d’obtenir une mémoire insuffisante d’Hibernate. Exception.

Des idées sur quelle serait la meilleure approche pour ce cas?

Dans mon expérience, j’ai travaillé avec de nombreux schémas d’une firebase database unique. Hibernate doit créer de nombreux EntityManagerFactory pour chaque schéma, ainsi que pour chaque firebase database.

Vous avez besoin d’un EntityManagerFactory pour chaque schéma ou chaque firebase database que vous utilisez.
Et vous savez, obtenir une EntityManagerFactory coûte très cher en ressources et en temps.
Après cela, obtenir un seul EntityManager est très bon marché.

Donc, dans votre cas, vous devez créer un N EntityManagerFactory, l’un d’eux pour chaque firebase database ou un schéma différent à partir des mêmes bases de données.

Comme il est coûteux de créer EntityManagerFactory, vous devez les créer uniquement si nécessaire et lorsque cela est nécessaire. Vous savez que vous devez attendre au moins 30 secondes ou plus pour que chacun d’entre eux soit disponible.

Afin d’éviter une exception de mémoire insuffisante, vous pouvez essayer de créer de 1 à N le nombre maximal d’entités EntityManagerFactory et voir si vos ressources peuvent la prendre en charge.

Si vous constatez cela lorsque vous arrivez à un numéro X et que cela survient toujours, le système plante, vous pouvez donc limiter le nombre simultané de EntityManagerFactory à ce nombre limite X.

Essayez et laissez-moi savoir vos résultats ou si vous avez besoin d’un exemple de code

Je pensais au problème de manière légèrement différente.

Selon ma compréhension

Votre exigence est de récupérer les données de différentes bases de données, même si vous ne le savez pas au moment du développement.

Alors, pourquoi vous essayez de mettre toute cette charge en veille prolongée pour gérer les connexions avec autant de bases de données.

Vous connaissez bien la firebase database principale.

Laissez la firebase database maître faire le rest.

Vous devez uniquement communiquer avec la firebase database principale et toute la charge nécessaire pour extraire les données des autres bases de données doit être conservée dans la firebase database principale.

Créez les liens DBL pour différentes bases de données dans la firebase database master.

Et maintenir les métadonnées requirejses aussi bien dans la firebase database principale.

Chaque fois que vous avez besoin de récupérer des données à partir d’une firebase database nouvellement ajoutée, vous n’avez qu’à demander à la firebase database principale.

Problèmes pouvant être résolus en utilisant DBLinks

  • Vous n’avez pas à exposer les informations d’identification de firebase database (de bases de données différentes) dans une table
  • Hibernate sera maintenu léger
  • Votre code Java sera maintenu propre
  • Toute modification apscope à une firebase database (structure, informations d’identification) reflétera immédiatement (dans une autre approche, vous devez redémarrer votre application après de tels changements dans la firebase database).

Une référence pour DBLink dans postgres

Nous avons des choses similaires: 1. Les bases de données en tant que client différent. Chaque client a le même schéma, nous n’avons donc qu’un seul gestionnaire d’entité. Donc, vous devez fournir hibernete via la classe d’implémentation de spi 2 et gérer via les propriétés:

hibernate.multi_tenant_connection_provider org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider

et hibernate.tenant_identifier_resolver org.hibernate.context.spi.CurrentTenantIdentifierResolver

“hibernate.multiTenancy”, “SCHEMA”

Voici un exemple comment le faire avec un cadre de spring

LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); emf.setJpaVendorAdapter(jpaVendorAdapter()); emf.setPersistenceUnitName("security"); Properties hibernateProperties = new Properties(); hibernateProperties.put("hibernate.cache.use_second_level_cache", "true"); hibernateProperties.put("hibernate.multiTenancy", "SCHEMA"); // do not load all metadata from standard db speadup startup hibernateProperties.put("hibernate.temp.use_jdbc_metadata_defaults", "false"); hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL9Dialect"); hibernateProperties.put("hibernate.multi_tenant_connection_provider", multiTenantConnectionProvider()); hibernateProperties.put("hibernate.tenant_identifier_resolver", currentTenantIdentifierResolver(tenant)); hibernateProperties.put("hibernate.show_sql", true); emf.setJpaProperties(hibernateProperties); emf.setJpaDialect(new HibernateJpaDialect()); LOG.info("LocalContainerEntityManagerFactoryBean bean created"); return emf;