从spring io你转移到堆栈溢出但是你没有解释多租户完整演示应用程序,它可以被看作是一个问题解决者事实上没有人对你的答案感到满意你现在可以分享一个多租户模式和单独数据库完整代码的工作演示任何人们可以友好地使用它的地方
package com.domain.model;
import javax.persistence.*;
@Entity
@Table
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int employeeId;
@Column
private String employeeName;
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
}
package com.domain.multitenancy;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
public class CurrentTenantIdentifierResolverimpl implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() {
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String tenantId = attr.getRequest().getParameter("tenantId");
return tenantId;
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
package com.domain.multitenancy;
import com.domain.master.MasterService;
import org.hibernate.service.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl;
import javax.sql.DataSource;
public class MultiTenantConnectionprovideImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
@Override
protected DataSource selectAnyDataSource() {
return MasterService.getDataSourceHashMap().get("tenantId1");
}
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
return MasterService.getDataSourceHashMap().get(tenantIdentifier);
}
}
package com.domain.master;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.util.HashMap;
public class MasterService {
public static HashMap<String, DataSource> getDataSourceHashMap() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/multiten");
dataSource.setUsername("root");
dataSource.setPassword("root");
DriverManagerDataSource dataSource1 = new DriverManagerDataSource();
dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
dataSource1.setUrl("jdbc:mysql://localhost:3306/multiten_1");
dataSource1.setUsername("root");
dataSource1.setPassword("root");
HashMap hashMap = new HashMap();
hashMap.put("tenantId1", dataSource);
hashMap.put("tenantId2", dataSource1);
return hashMap;
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.domain"/>
<mvc:annotation-driven/>
<context:property-placeholder location="classpath:application.properties"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="packagesToScan">
<list>
<value>com.domain.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
<prop key="hibernate.multiTenancy">DATABASE</prop>
<prop key="hibernate.tenant_identifier_resolver">com.domain.multitenancy.CurrentTenantIdentifierResolverimpl</prop>
<prop key="hibernate.multi_tenant_connection_provider">com.domain.multitenancy.MultiTenantConnectionprovideImpl</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
#Application.properties file in classpath
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/multiten
jdbc.username = root
jdbc.password = root
hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql = true
hibernate.format_sql = false
我举了这个例子
这些是我得到的错误:
org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是 org.springframework.transaction.CannotCreateTransactionException:无法为事务打开 Hibernate Session;嵌套异常是 org.hibernate.HibernateException: SessionFactory 配置为多租户,但没有指定租户标识符 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:979) org.springframework.web.servlet.FrameworkServlet.doPost (FrameworkServlet.java:869) javax.servlet.http.HttpServlet.service(HttpServlet.java:660) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) javax.servlet.http.HttpServlet.service (HttpServlet.java:741) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
根本原因 org.springframework.transaction.CannotCreateTransactionException:无法为事务打开休眠会话;嵌套异常是 org.hibernate.HibernateException: SessionFactory 配置为多租户,但没有指定租户标识符 org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:544) org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction (AbstractPlatformTransactionManager.java:373) org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427) org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276) org.springframework.transaction.interceptor .
根本原因 org.hibernate.HibernateException:为多租户配置了 SessionFactory,但未指定租户标识符 org.hibernate.internal.AbstractSessionImpl.(AbstractSessionImpl.java:85) org.hibernate.internal.SessionImpl.(SessionImpl.java:239) org.hibernate.internal.SessionFactoryImpl$SessionBuilderImpl.openSession(SessionFactoryImpl.java:1618) org.hibernate.internal.SessionFactoryImpl.openSession(SessionFactoryImpl.java:978) org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:第436章) org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)427)org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276)org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)org.springframework.aop.framework.ReflectiveMethodInvocation.proceed( ReflectiveMethodInvocation.java:179) org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) com.sun.proxy.$Proxy22.save(未知来源) com.domain.controller.EmployeeController.saveEmployee(EmployeeController. java:35) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) java.lang.reflect.Method.invoke(Unknown Source)组织。springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) org.springframework.web.servlet.mvc.method. annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832) org.springframework.web.servlet.mvc.method.annotation。 RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) org.springframework.web.servlet.DispatcherServlet。doDispatch(DispatcherServlet.java:961) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) org.springframework.web。 servlet.FrameworkServlet.doPost(FrameworkServlet.java:869) javax.servlet.http.HttpServlet.service(HttpServlet.java:660) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) javax.servlet。 http.HttpServlet.service(HttpServlet.java:741) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)第967章java:843) javax.servlet.http.HttpServlet.service(HttpServlet.java:741) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)第967章java:843) javax.servlet.http.HttpServlet.service(HttpServlet.java:741) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
注意服务器日志中提供了根本原因的完整堆栈跟踪。