postgres example conectar con java database postgresql hibernate

java - example - spring.jpa.database-platform postgres



Hibernar múltiples conexiones dinámicamente cambiando. (3)

Sé que hay preguntas similares sobre este escenario, sin embargo, ninguna de ellas que he encontrado coincide con mi caso y me gustaría tener una solución que no afecte el rendimiento. Tengo que hacer múltiples conexiones a diferentes bases de datos (todas postgresql) y el problema es que las bases de datos pueden ser muchas, ya que se crean continuamente.

En este momento solo tendré una base de datos conocida que se utilizará para almacenar las cadenas de conexión de las otras bases de datos. Estas bases de datos pueden ser 1, 2, 5, 10 o N, lo difícil es que, desde mi punto de vista, nunca sabré cuántas serán y cuál será su ubicación y credenciales (todas almacenadas en mi base de datos central). El caso de uso funciona de una manera en la que para realizar una operación en una de estas bases de datos, primero tengo que buscar en la base de datos central la ubicación de la base de datos que necesitamos y luego realizar la operación.

En este momento, he podido realizar la operación cantando SessionFactory, pero la operación es demasiado lenta incluso para una simple selección / actualización, y mi preocupación es que cuando se realizan varias solicitudes, podemos obtener de Hibernate un Out of Memory Excepción.

¿Alguna idea sobre cuál sería el mejor enfoque para este caso?


En mi experiencia, trabajé con muchos esquemas de una sola base de datos. Hibernate necesita crear una gran cantidad de EntityManagerFactory para cada esquema único, y también para cada base de datos.

Necesita un EntityManagerFactory para cada esquema o cada base de datos en la que esté trabajando.
Y usted sabe que obtener un EntityManagerFactory es muy costoso en términos de recursos y tiempo.
Después de eso conseguir un solo EntityManager es muy barato.

Entonces, en su caso, debe crear una N EntityManagerFactory, una de ellas para cada Base de datos diferente o un esquema diferente de las mismas bases de datos.

Como es costoso crear EntityManagerFactory, debe crearlos solo si es necesario y cuando sea necesario, y sabe que debe esperar casi 30 segundos o más para obtenerlos.

Para evitar una excepción de memoria insuficiente, puede intentar probar para crear de 1 a N, el número máximo de EntityManagerFactory y ver si sus recursos pueden admitir esto.

Si ve eso cuando llega a un número X y supera este bloqueo del sistema, siempre puede limitar el número simultáneo de EntityManagerFactory a este número límite X.

Pruébelo y hágame saber sus resultados o si necesita algún ejemplo de código


Estaba pensando en el problema de una manera un poco diferente.

Según mi entendimiento

Su requisito es recuperar los datos de diferentes bases de datos, incluso si no lo sabe en el momento del desarrollo.

Entonces, ¿ por qué está intentando poner toda esta carga en hibernación para administrar las conexiones con tantas bases de datos?

Usted es muy consciente de la base de datos maestra que es eso.

Deje que la base de datos maestra haga el resto de las cosas.

Solo debe comunicarse con la base de datos maestra y toda la carga para recuperar datos del resto de las bases de datos debe mantenerse en la base de datos maestra.

Cree los DBLinks para diferentes bases de datos dentro de la base de datos maestra.

Y mantener los metadatos requeridos también en la base de datos maestra.

Siempre que necesite recuperar datos de una base de datos recién agregada o algo así, solo pregunte en la base de datos maestra.

Problemas que pueden resolverse utilizando DBLinks

  • No tiene que exponer las credenciales de la base de datos (de diferentes bases de datos) en ninguna tabla
  • Hibernate se mantendrá ligero ponderado
  • Tu código de Java se mantendrá limpio
  • Cualquier cambio realizado en cualquier base de datos (estructura, credenciales) se reflejará de inmediato (en otro enfoque, debe reiniciar su aplicación después de dichos cambios en la base de datos)

Una referencia para DBLink en postgres


Tenemos cosas similares: 1..N bases de datos como cliente diferente. Cada cliente tiene el mismo esquema, por lo que solo tenemos 1 administrador de entidades. Por lo tanto, debe proporcionar hibernete a través de la clase de implementación spi 2 y el manejo a través de las propiedades:

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

y hibernate.tenant_identifier_resolver org.hibernate.context.spi.CurrentTenantIdentifierResolver

"hibernate.multiTenancy", "SCHEMA"

Aquí hay un ejemplo de cómo hacerlo con el framework 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;