2016-10-26 3 views
1

Wie initialisiere ich mehrere Datenbanken mit hbm2dll mit LocalContainerEntityManagerFactoryBean?Hbm2dll Initialisierung in Hibernate JPA mit mehreren Datenbanken + Multitenancy

Ich verwende verschiedene Datenquellen pro Mieter in MultiTenancy. Ich habe eine Standarddatenquelle mit der ID "dataSource" in ApplicationContext.xml und ich erzeuge eine Datenquelle pro Mandant mit den Eigenschaften von "dataSource", aber die URL ändern. Ich füge sie in einem benutzerdefinierten MapDataSourceLookup hinzu.

Ich habe versucht, JPA-Initialisierung mit LocalContainerEntityManagerFactoryBean zu konfigurieren.

<bean class="org.springframework.orm.jpa.JpaTransactionManager" 
    id="transactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

<bean 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    id="entityManagerFactory" > 
    <property name="persistenceUnitManager" ref="pum"/> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="databasePlatform" value="${database.dialect}" /> 
     </bean> 
    </property> 
    <property name="jpaPropertyMap"> 
     <map> 
      <entry key="hibernate.multi_tenant_connection_provider" value-ref="multitenancyConnectionProvider"/> 
      <entry key="hibernate.tenant_identifier_resolver" value-ref="tenantResolver"/>            
     </map> 
    </property> 
</bean> 

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"> 
    <property name="dataSourceLookup" ref="dataSourceLookup"/> 
    <property name="persistenceXmlLocations"> 
     <list> 
      <value>classpath:META-INF/persistence.xml</value> 
     </list> 
    </property> 
</bean> 


<bean class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close" 
    id="dataSource"> 
    <property name="driverClass" value="${database.driverClassName}" /> 
    <property name="jdbcUrl" value="${database.url}" /> 
    <property name="username" value="${database.username}" /> 
    <property name="password" value="${database.password}" /> 
    <property name="idleConnectionTestPeriod" value="${database.idleConnectionTestPeriod}" /> 
    <property name="idleMaxAge" value="${database.idleMaxAge}" /> 
    <property name="maxConnectionsPerPartition" value="${database.maxConnectionsPerPartition}" /> 
    <property name="minConnectionsPerPartition" value="${database.minConnectionsPerPartition}" /> 
    <property name="partitionCount" value="${database.partitionCount}" /> 
    <property name="acquireIncrement" value="${database.acquireIncrement}" /> 
    <property name="statementsCacheSize" value="${database.statementsCacheSize}" /> 
    <property name="releaseHelperThreads" value="${database.releaseHelperThreads}" /> 
</bean> 

Ich habe eine benutzerdefinierte @component dataSourceLookup, die injiziert wird, und es ist, die verschiedenen Datenquellen auf diese Weise zu schaffen.

 //Add new datasource with configuration from "dataSource" and new url per tenant 
     BoneCPDataSource customDataSource = new BoneCPDataSource(defaultDataSource.getConfig()); 
     customDataSource.setJdbcUrl(props.getProperty("database.url")); 
     addDataSource(tenantId, customDataSource); 

     logger.info("Configuring tenant: " + tenantId + " Properties: " + customDataSource.toString()); 

Das ist mein persistence.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
<persistence-unit name="persistenceUnit" 
    transaction-type="RESOURCE_LOCAL">  
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>  
    <properties>    
     <property name="hibernate.hbm2ddl.auto" value="update" /> 
     <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" /> 
     <property name="hibernate.connection.charSet" value="UTF-8" /> 
     <property name="hibernate.show_sql" value="true" />   

     <!-- Multi-tenancy properties --> 
     <property name="hibernate.multiTenancy" value="DATABASE" /> 
    </properties> 
</persistence-unit> 

Im Augenblick ist die einzige Regelung, die erstellt wird, ist die Standarddatenbank. Die Datenquellen, die auf andere Datenbanken verweisen, werden jedoch nicht erstellt. Dass zu diesem Fehler, wenn ich versuche zu einem Benutzer zuzugreifen, da USER-Tabelle existiert nicht:

Verursacht durch: org.hsqldb.HsqlException: Benutzer fehlt Privileg oder Objekt nicht gefunden: USER

Antwort

0

Ich habe zu lösen Verwenden Sie dazu eine benutzerdefinierte erweiterte Klasse von LocalContainerEntityManagerFactoryBean und implementieren Sie die Methode postProcessEntityManagerFactory (EntityManagerFactory emf, PersistenceUnitInfo pui).

In dieser Methode, ich Schleife verschiedene Datenquellen und erstellen Sie Entitymanagerfactory mit dieser Datenquelle in jeder Iteration, ich weiß, es ist nicht die beste, aber wenn Sie eine bessere Lösung wusste, würde ich gerne hören :). Schemaexport wird momentan nicht von Hibernate in Multitenancy unterstützt und das ist die Lösung, die ich gefunden habe.

Verwandte Themen