Hibernate的问题';s多租户和Spring
我试图掌握如何使用Hibernate、Spring和MySQL实现多租户。对于第一个游乐场示例,我选择了单独的数据库方法:每个租户都有自己的数据库,名为accodingly。此外,还使用另一个数据库来管理租户。特定于租户的数据库保存一些员工数据。对于第一种方法,我不强制用户进行身份验证 我发现很难获得关于这个主题的全面教程,这就是为什么我现在有点迷茫的原因。当我尝试部署Tomcat时,会收到以下消息:Hibernate的问题';s多租户和Spring,spring,hibernate,spring-mvc,multi-tenant,Spring,Hibernate,Spring Mvc,Multi Tenant,我试图掌握如何使用Hibernate、Spring和MySQL实现多租户。对于第一个游乐场示例,我选择了单独的数据库方法:每个租户都有自己的数据库,名为accodingly。此外,还使用另一个数据库来管理租户。特定于租户的数据库保存一些员工数据。对于第一种方法,我不强制用户进行身份验证 我发现很难获得关于这个主题的全面教程,这就是为什么我现在有点迷茫的原因。当我尝试部署Tomcat时,会收到以下消息: WARN : org.hibernate.engine.jdbc.connections.in
WARN : org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator - Unable to instantiate specified class [sdb.persistence.TenantResolverImpl]
java.lang.ClassCastException: sdb.persistence.TenantResolverImpl cannot be cast to org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider
at org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:100)
at org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:45)
...
ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'staffSessionFactory' defined in ServletContext resource [/WEB-INF/spring/appServlet/spring-data.xml]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to instantiate specified multi-tenant connection provider [sdb.persistence.TenantResolverImpl]
...
Caused by: org.hibernate.service.spi.ServiceException: Unable to instantiate specified multi-tenant connection provider [sdb.persistence.TenantResolverImpl]
at org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:104)
at org.hibernate.engine.jdbc.connections.internal.MultiTenantConnectionProviderInitiator.initiateService(MultiTenantConnectionProviderInitiator.java:45)
这是我的Java类的结构:
xml配置分为三个文件。1. <代码>servlet context.xml:
spring data.xml
:
org.hibernate.dialogue.mysql5dialogue
符合事实的
sdb.domain.Tenant
org.hibernate.dialogue.mysql5dialogue
符合事实的
平民的
模式
sdb.persistence.ConnectionProviderImpl
sdb.persistence.TenantResolverImpl
spring mvc.xml
:
/WEB-INF/pages/
.jsp
现在来看Java类。我的DAO都有一个会话工厂字段:
@存储库
公共类TenantDaoImpl实现TenantDao{
@自动连线
私人SessionFactory租户SessionFactory;
...
@存储库
公共类StaffDaoImpl实现StaffDao{
@自动连线
私人SessionFactory员工SessionFactory;
控制员:
@控制器
公共类家庭控制器{
@自动连线
斯塔夫道斯塔夫道;
@RequestMapping(value=“/{companyName}/{staffId}”,method=RequestMethod.GET)
公共字符串google(模型模型,@PathVariable字符串companyName,@PathVariable字符串staffName){
List staff=staffDao.getStaff();
//是的,我知道这个功能实际上应该驻留在Dao或服务层中
可选的foundStaff=staff.stream().filter(staff->staff.getNames().equals(staffName)).findFirst();
if(foundStaff.isPresent()){
model.addAttribute(“foreName”,foundStaff.get().getForeName());
model.addAttribute(“姓氏”,foundStaff.get().getNames());
}
model.addAttribute(“companyName”,companyName);
返回“工作人员”;
}
}
最后,是与多租户相关的源代码。TenantResolverImpl.java
:
公共类TenantResolverImpl实现CurrentTenantIdentifierResolver{
@凌驾
公共字符串resolveCurrentTenantIdentifier(){
如果(FacesContext.getCurrentInstance()!=null){
//我不知道这是否行得通-这行是从其他地方抄来的
返回FacesContext.getCurrentInstance().getExternalContext().getRequestServerName();
}
返回null;
}
//不确定如何使用此方法。。。
@凌驾
public boolean validateExistingCurrentSessions(){return true;}
}
ConnectionProviderImpl.java
:
公共类ConnectionProviderImpl实现了MultiTenantConnectionProvider{
私有地图数据源;
@自动连线
租户道租户道;
@凌驾
公共连接getAnyConnection()引发SQLException{
//可能应该返回“dummy”之类的连接
返回getConnection(“谷歌”);
}
@凌驾
公共连接getConnection(字符串租户标识符)引发SQLException{
if(tenantDao.containtenantWithName(tenantIdentifier)){
if(!dataSources.containsKey(租户标识符)){
ComboPooledDataSource=新ComboPooledDataSource(“示例”);
试一试{
setDriverClass(“com.mysql.jdbc.Driver”);
}捕获(PropertyVetOe异常){
e、 printStackTrace();
返回null;
}
setJdbcUrl(“jdbc:mysql://localhost:3306/“+租户证明人);
setUser(“根”);
dataSource.setPassword(“根”);
dataSources.put(tenantIdentifier,dataSource);
}
返回dataSources.get(tenantIdentifier.getConnection();
}
返回null;
}
...
}
由于我(但)对技术的肤浅理解,我猜代码中有很多错误/缺点。请随意批评任何值得注意的东西。希望你自己能解决它,如果不是的话,这里是我的提示: 更改属性,您应该完成;)
sdb.persistence.ConnectionProviderImpl
sdb.persistence.TenantResolverImpl
<prop key="hibernate.tenant_identifier_resolver">sdb.persistence.ConnectionProviderImpl</prop>
<prop key="hibernate.multi_tenant_connection_provider">sdb.persistence.TenantResolverImpl</prop>