2014-11-12 35 views
9

Ist es möglich, Spring Boot so zu konfigurieren, dass ein MultiTenantConnectionProvider verwendet wird, so dass jeder Client meines Systems eine Verbindung zu seiner eigenen privaten Datenbank herstellt?Spring Boot + Spring Daten mit mehreren Mandanten

Insbesondere Ich suche die eingebaute in Hibernate Unterstützung für Multi-Tenant zu verwenden:

Und dies ist ein Beispiel für die Art von Config ich nach bin, aber ich kann nicht herausfinden, wie diese Einrichtung in einer Frühlings-Boot zu verwenden:

Ich habe versucht, das Hinzufügen dieser Eigenschaften zu application.properties:

spring.jpa.hibernate.multiTenancy=DATABASE 
spring.jpa.hibernate.tenant_identifier_resolver=com.mystuff.MyCurrentTenantIdentifierResolver 
spring.jpa.hibernate.multi_tenant_connection_provider=com.mystuff.MyMultiTenantConnectionProviderImplX 

ich auch meine eigene Codierung oben habe versucht CurrentTenantIdentifierResolver und MultiTenantConnectionProvider und versucht, diese von meinem Haupt @Configuration Bohne dienen:

@Bean 
public CurrentTenantIdentifierResolver currentTenantIdentifierResolver() { 
    return new CurrentTenantIdentifierResolver() { 
     public String resolveCurrentTenantIdentifier() { 
      // this is never called ... 
     } 
     public boolean validateExistingCurrentSessions() { 
      // this is never called ... 
     } 
    }; 
} 

@Bean 
public MultiTenantConnectionProvider multiTenantConnectionProvider() { 
    return new AbstractMultiTenantConnectionProvider() { 
     protected ConnectionProvider getAnyConnectionProvider() { 
      // this is never called ... 
     } 
     protected ConnectionProvider selectConnectionProvider(String s) { 
      // this is never called ... 
     } 
    }; 
} 

Nichts davon scheint zu beeinflussen, so ist meine Frage, wie Spring-Boot/Spring-Daten wirklich erhalten werden, um diese Multi-Tenant-Klassen zu verwenden?

Danke für Ihre Hilfe!

+0

Siehe meine Frage [hier] (https://stackoverflow.com/questions/44366221/hibernate-multenancy-with-spring-jpa).
Ich benutze eine 'LocalContainerEntityManagerFactoryBean' und es funktioniert.
Aber ich verstehe nicht den Unterschied zwischen diesem und '.yml'or'.properties'.
Ich stimme @MDeinum zu, in 'Yml' kontrolliert Hibernate den Lebenszyklus von' multiTenantConnectionProvider' und 'CurrentTenantIdentifierResolver'. Aber ich weiß nicht warum. – linghu

Antwort

6

Any property für JPA/Ruhezustand, der nicht definiert ist, kann mit der spring.jpa.properties-Eigenschaft im application.properties festgelegt werden.

Die Probe Sie verlinkt auf hat 3 Eigenschaften für Multitenancy:

<prop key="hibernate.multiTenancy">SCHEMA</prop> 
<prop key="hibernate.tenant_identifier_resolver">com.webapp.persistence.utility.CurrentTenantContextIdentifierResolver</prop> 
<prop key="hibernate.multi_tenant_connection_provider">com.webapp.persistence.utility.MultiTenantContextConnectionProvider</prop> 

Das Spring-Boot umgewandelt würden die folgenden Eigenschaften in der application.properties-Datei sein.

spring.jpa.properties.hibernate.multiTenancy=SCHEMA 
spring.jpa.properties.hibernate.tenant_identifier_resolver=com.mystuff.MyCurrentTenantIdentifierResolver 
spring.jpa.properties.hibernate.multi_tenant_connection_provider=com.webapp.persistence.utility.MultiTenantContextConnectionProvider 

Für Ihre Situation (wie in Ihrer Frage angegeben).

Es funktioniert nicht mit Spring-Manager-Beans, da der Ruhezustand den Lebenszyklus dieser Instanzen steuert.

Weitere Eigenschaften finden Sie im Spring Boot reference guide.

+0

Danke, ich habe die '.properties' vermisst. Bit (das Docco ist im Nachhinein klar, aber ich habe es die ersten paar Male vermisse ich es gelesen). Eine kleine Herausforderung jetzt um den Lebenszyklus, wie Sie hervorgehoben haben. Speziell Zugriff auf andere Spring-Services über den ConnectionProvider erhalten. Ich habe versucht, einen statischen Verweis auf den Dienst zu halten, den ich brauche, aber das Hibernate-Zeug wird zuerst erstellt, so dass es null ist, wenn ich es brauche. Fallback ist einfach nicht Spring Dienste in diesen Klassen zu verwenden, aber es macht den Code unordentlich. Wenn Sie Ideen auf dieser Seite haben, würde ich sie gerne hören. – zonski

+1

Obwohl ein bisschen hacky, könnten Sie 'ContextLoader.getCurrentWebApplicationContext' verwenden, um Zugriff auf den Kontext zu erhalten und die Suche durchzuführen. Oder erstellen Sie eine Hilfsklasse, mit der Sie die Dienste abrufen können. –

+1

Ja, danke - Ich habe beide versucht, aber was auch immer Spring Boot tut bewirkt, dass der MultiTenantConnectionProvider instanziiert wird, bevor der Kontext existiert, also ContextLoader. getCurrentWebApplicationContext() ist null, wenn getAnyConnectionProvider() zum ersten Mal aufgerufen wird, und Hilfsklassen können die Dienste auch an dieser Stelle nicht finden. Ich denke, ich bin fest mit nur nicht in der Lage, Spring-Dienste aus dem MultiTenantConnectionProvider verwenden. Schade, aber nicht das Ende der Welt. Vielen Dank für Ihre Hilfe, wirklich zu schätzen wissen! – zonski

Verwandte Themen