2014-10-02 92 views
1

在我的应用程序中,每个客户端都有多个数据库。我想按照登录到应用程序中的客户端访问数据库。在Hibernate中动态创建SessionFactory

有两种选择:
1)在hibernate-config.xml文件中使用多个SessionFactory条目。
2)重复的hibernate pojo文件。

但我想在运行时创建LocalSessionFactoryBean,SessionFactory,TransactionManager所有这些。那我该怎么做? 我不想在hibernate-config.xml文件中做多个SessionFactory和DataSource条目。

我已经试过下面的代码片段。

@Configuration 
@EnableTransactionManagement 
public class PersistenceHibernateConfig 
{ 

    private String driverClassName; 

    private String url; 

    String   hibernateDialect; 

    boolean   hibernateShowSql; 

    @Bean 
    public LocalSessionFactoryBean alertsSessionFactoryBean() 
    { 
     final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
     sessionFactory.setDataSource(this.restDataSource()); 
     sessionFactory.setPackagesToScan(new String[] { "com.ezdi.cac.bean.table" }); 
     sessionFactory.setHibernateProperties(this.hibernateProperties()); 

     return sessionFactory; 
    } 

    @Bean 
    public DataSource restDataSource() 
    { 
     final DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
     dataSource.setDriverClassName(this.driverClassName); 
     dataSource.setUrl(this.url); 
     dataSource.setUsername("root"); 
     dataSource.setPassword("root"); 

     return dataSource; 
    } 

    @Bean 
    public HibernateTransactionManager transactionManager() 
    { 
     final HibernateTransactionManager txManager = new HibernateTransactionManager(); 
     txManager.setSessionFactory(this.alertsSessionFactoryBean().getObject()); 

     return txManager; 
    } 

    @Bean 
    public PersistenceExceptionTranslationPostProcessor exceptionTranslationPostProcessor() 
    { 
     return new PersistenceExceptionTranslationPostProcessor(); 
    } 

    @Bean 
    public PersistenceExceptionTranslator exceptionTranslator() 
    { 
     return new HibernateExceptionTranslator(); 
    } 

    final Properties hibernateProperties() 
    { 
     return new Properties() 
     { 
      { 
       this.put("persistence.dialect", PersistenceHibernateConfig.this.hibernateDialect); 
       this.put("hibernate.show_sql", PersistenceHibernateConfig.this.hibernateShowSql); 
      } 
     }; 

    } 

    /** 
    * @return the driverClassName 
    */ 
    public String getDriverClassName() 
    { 
     return driverClassName; 
    } 

    /** 
    * @param driverClassName the driverClassName to set 
    */ 
    public void setDriverClassName(String driverClassName) 
    { 
     this.driverClassName = driverClassName; 
    } 

    /** 
    * @return the url 
    */ 
    public String getUrl() 
    { 
     return url; 
    } 

    /** 
    * @param url the url to set 
    */ 
    public void setUrl(String url) 
    { 
     this.url = url; 
    } 

    /** 
    * @return the hibernateDialect 
    */ 
    public String getHibernateDialect() 
    { 
     return hibernateDialect; 
    } 

    /** 
    * @param hibernateDialect the hibernateDialect to set 
    */ 
    public void setHibernateDialect(String hibernateDialect) 
    { 
     this.hibernateDialect = hibernateDialect; 
    } 

    /** 
    * @return the hibernateShowSql 
    */ 
    public boolean isHibernateShowSql() 
    { 
     return hibernateShowSql; 
    } 

    /** 
    * @param hibernateShowSql the hibernateShowSql to set 
    */ 
    public void setHibernateShowSql(boolean hibernateShowSql) 
    { 
     this.hibernateShowSql = hibernateShowSql; 
    } 

} 

但每当我经过的LocalSessionFactoryBean并通过HibernateTransactionManager的得到的SessionFactory,我得到了它null.I不知道为什么我得到空的原因是什么?

回答

3

您应该了解一下为此需求量身定制的Hibernate多租户。从休眠4.x开始,它可用,并建议使用而不是使用多个SessionFactory。请通过这个post

0

所有后面只有在Web应用程序的意义,但因为这个问题有弹簧MVC标签...

假设你有办法从连接的用户名获得数据库名称,不访问数据库直到用户登录并建立会话,您可以简单地将所有内容放在会话范围内。

只需添加一个范围注释相关豆类:

@Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.INTERFACES) 

使用提供的绑定,通过接口豆一JDP代理(至少应为数据源和SessionFactory的情况下,也可用于事务管理如果正常使用)。如果因为需要使用类而中断,请使用proxyMode=ScopedProxyMode.TARGET_CLASS

这样,你甚至可以将会话工厂绑定到一个(singleton bean)Dao中,并且感谢范围代理,每个用户都将使用它自己的。

细腻的部分是编写getUrl()方法,因为它必须返回正确的url。但是,您也可以使用会话作用域bean来存储url并在登录时存储url。

相关问题