2016-10-26 5 views
1

Как инициализировать несколько баз данных с помощью hbm2dll с помощью LocalContainerEntityManagerFactoryBean?Инициализация Hbm2dll в Hibernate JPA с несколькими базами данных + Многопользовательская связь

Я использую разные источники данных для каждого арендатора в MultiTenancy. У меня есть источник данных по умолчанию с идентификатором «dataSource» в ApplicationContext.xml, и я генерирую источник данных для каждого арендатора, используя свойства «dataSource», но изменяя URL-адрес. Я добавляю их в пользовательский MapDataSourceLookup.

Я попытался настроить инициализацию JPA с помощью LocalContainerEntityManagerFactoryBean.

<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> 

У меня есть пользовательский @component dataSourceLookup, который впрыскивается, и это создает различные источники данных, на этом пути.

 //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()); 

Это мой 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> 

Сейчас единственная схема, которая создается в базе данных по умолчанию. Но источники данных, которые указывают на другие базы данных, не создаются. Это произведет эту ошибку, когда я пытаюсь получить доступ к пользователю, так как таблица USER не существует:

Вызванные: org.hsqldb.HsqlException: пользователь не имеет привилегий или объект не найден: USER

ответ

0

Я должен решить используя специальный расширенный класс LocalContainerEntityManagerFactoryBean и реализующий метод postProcessEntityManagerFactory (EntityManagerFactory emf, PersistenceUnitInfo pui).

В этом методе я петлю различные источники данных и создаю entitymanagerfactory с использованием этого источника данных на каждой итерации, я знаю, что это не самое лучшее, но если бы вы знали лучшее решение, я бы хотел послушать :). На данный момент Schemaexport не поддерживается спящим режимом в многопользовательском режиме, и это решение, которое я нашел.

 Смежные вопросы

  • Нет связанных вопросов^_^