java - query - spring data repository
Spring Data+JPA con mĂșltiples fuentes de datos pero solo un conjunto de Repositorios (1)
Si realmente está utilizando los diferentes DataSource
en una forma de múltiples inquilinos (esencialmente asignando una solicitud a un DataSource
y manteniéndolo en toda la solicitud), debería consultar AbstractRoutingDataSource
. Básicamente, proporciona una forma de mantener un Map
de DataSource
, así como un método de devolución de llamada para devolver una clave que se utilizará para buscar el DataSource
que se utilizará eventualmente. La implementación de este método generalmente busca alguna clave de enlace de hilo y la devuelve (o incluso asigna eso a una clave de mapa de DataSource
a su vez). Solo debes asegurarte de que algún componente web vincule esa clave al hilo en primer lugar.
Si tiene eso en su lugar, su configuración Spring simplemente configura un bean para su subclase de AbstractRoutingDataSource
y canaliza el mapa de DataSources
en él. La configuración de Spring Data JPA se mantiene de manera predeterminada. El EntityManagerFactoryBean
refiere a AbstractRoutingDataSource
y usted tiene un solo elemento <jpa:repositories />
.
He estado investigando esto un montón hoy y estoy empezando a pensar que lo que quiero hacer puede que no sea posible, así que me estoy dirigiendo a ti, oh poderoso Stackoverflow, en busca de ayuda.
Estoy creando una plataforma de servicios RESTful en Java, con Spring Data 3.1.2 + JPA como mi capa de persistencia (como se documenta here ). Todos mis objetos de modelo de datos se implementan como interfaces que extienden la interfaz Spring JpaRepository. Lo tengo todo conectado y funcionando bien con una única fuente de datos, como se muestra en este ejemplo (tenga en cuenta que la fuente de datos que se muestra es Derby, pero eso es solo para fines de desarrollo; en producción, usaremos Oracle):
<jpa:repositories base-package="com.my.cool.package.repository"/>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
<property name="packagesToScan" value="com.my.cool.package" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
</bean>
<bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="url" value="jdbc:derby:derbyDB" />
<property name="username" value="dev" />
<property name="password" value="notARealPassword" />
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
</bean>
El problema es que esta aplicación necesitará conectarse a varias bases de datos (Oracle). Las credenciales incluidas con cada solicitud entrante contendrán un campo que le indica a la aplicación a qué base de datos debe acceder para cumplir con esa solicitud. Los esquemas para cada base de datos son los mismos, por lo que no hay necesidad de interfaces de repositorio separadas para cada base de datos.
Después de una buena cantidad de Google, está claro que este es un escenario común. Esto es:
- múltiples bases de datos con Spring Data JPA
- Spring + Hibernate + JPA + bases de datos múltiples
- cómo configurar jpa de datos de primavera con múltiples fuentes de datos
Y aquí hay una publicación en el blog de un (¿anterior?) Desarrollador de Spring, que no es realmente relevante para el tema en cuestión, pero alguien lo menciona en los comentarios, y el autor responde con algo de información:
El tema que parece estar surgiendo es que la manera de resolver este problema es definir múltiples EntityManagerFactories y conectar cada una de ellas a los repositorios apropiados, como:
<jpa:repositories base-package="com.my.cool.package.repository1" entity-manager-factory-ref="firstEntityManagerFactory" />
<jpa:repositories base-package="com.my.cool.package.repository2" entity-manager-factory-ref="secondEntityManagerFactory" />
Sin embargo, como he mencionado, quiero reutilizar mi repositorio en todas las fuentes de datos, por lo que este enfoque no parece funcionar.
Sé que no hay manera de evitar que la lógica en mi código tome la información relevante de la solicitud y la use para determinar qué fuente de datos (o EntityManagerFactory) usar. La parte con la que estoy luchando es cómo obtener un identificador para esa fuente de datos / EntityManagerFactory e "inyectarlo" en mis objetos del repositorio. ¿Algunas ideas?