我是Hibernate的新手。在我的代码中,到DB的连接是用Hikari数据源管理的。
我的代码现在是多租户的,但它为所有租户管理相同的hibernate方言。
**是否可以创建一个配置,使每个租户都可以使用不同的方言?**方言的类型可以作为租户的属性提供。
以下是实体ManagerFactory的示例:
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
Map<String, Object> jpaProperties = new HashMap<>();
jpaProperties.put(..., ...);
jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, "myDialect");
LocalContainerEntityManagerFactoryBean emfBean = new LocalContainerEntityManagerFactoryBean();
emfBean.setPackagesToScan(new String[] {MyEntity.class.getPackage().getName()});
emfBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
emfBean.setJpaPropertyMap(jpaProperties);
return emfBean;
}
编辑
我在看这个solution:它建议为每个方言创建一个复制的LocalContainerEntityManagerFactoryBean。我不明白的是,我如何分辨何时使用一个EntityManager(MySQL),何时使用另一个(Postgres或MsSQL):solution区分实体(每个实体都有自己的DB),但在我的情况下,所有实体都在所有DB上。是歧视的房客。
举例来说:如果我创建LocalContainerEntityManagerFactoryBean的第二个示例(即msSQLEntityManagerFactory())设置了SQL Server的方言,应用程序无法启动:
Application failed to start due to an exceptionorg.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'javax.persistence.EntityManagerFactory' available:
expected single matching bean but found 2:
msSQLEntityManagerFactory,entityManagerFactory
3条答案
按热度按时间kmbjn2e31#
这是不可能的,因为方言会影响某些引用规则等。你不能只是在运行时根据租户标识符“换出”。只需创建两个持久性单元,每个持久性单元针对每种数据库类型指向不同的数据源。您将不得不以某种方式根据您的租户标识符查找适当的
EntityManager
/EntityManagerFactory
,这使得当您想要使用Spring Data JPA时变得有点困难,因为它需要实体管理器工厂的编译静态名称引用。也许您可以创建一个自定义的EntityManagerFactory
,根据租户标识符将所有方法调用委托给适当的示例。总的来说,这并不是那么容易,你可能要做很多的试验和错误。IMO最好是有一个单独的应用程序部署与单独的配置,如果可能的话,每个数据库类型。
yrwegjxp2#
我终于找到了解决这个问题的办法。我设法通过为每种方言(在本例中为MySQL、Postgres和MS SQL Server)创建一个实体管理器工厂来解决方言的问题。
为EntityManagerFactory创建一个bean,并返回该接口的代理,在处理程序中,根据您的逻辑,您可以切换使用哪个EMF来适应所使用的数据源。
我已经为此创建了一个视频,因为它似乎没有在线文档。
Session Scoped Connection
这与您试图实现的目标非常相似,但在我的情况下,用户提供凭据,因此它更加复杂。
zlhcx6iw3#
@Tsvetelin的回答给我指出了正确的方向,但是,在应用它之后,我开始遇到另一个库的问题,比如Hazelcast,它被用作二级缓存。
所以,这就是我所做的:
1.我没有创建
EntityManagerFactory
bean,而是创建了一个示例化DynamicTenantEntityManagerFactoryBean
的LocalContainerEntityManagerFactoryBean
。getPackagesToScan()
和additionalProperties()
是读取Sping Boot 在应用程序上下文上设置的参数的函数。DynamicTenantEntityManagerFactoryBean
扩展LocalContainerEntityManagerFactoryBean
并覆盖createNativeEntityManagerFactory()
,使用与@tsvetelin-yakimov相同的技术