我在使用 GlassFish 3.1.2 作为 Java EE 容器使用 Hibernate 4.1.7 和 EJB 3.1 实现多租户应用程序时遇到问题 目前有一个实现 org.hibernate.context.spi.CurrentTenantIdentifierResolver 的类,它标识登录的租户获取使用此代码登录的用户:
@Override
public String resolveCurrentTenantIdentifier() {
try {
SessionContext context = ServiceLocator.locate(SessionEjbContext.class).getSessionContext();
String userName = context.getCallerPrincipal().getName();
AppLogger.info("current tenant identifier [" + userName + "]");
return userName;
} catch (Throwable e) {
AppLogger.info("erro lookup");
}
return "default";
}
SessionContext.class 是这样实现的
@Stateful
@SessionScoped
public class SessionEjbContext {
@Resource
private SessionContext sessionContext;
public SessionContext getSessionContext() {
return sessionContext;
}
}
然后将 id 提供给扩展 org.hibernate.service.jdbc.connections.spi.AbstractMultiTenantConnectionProvider 的类,该类实现 ConnectionProvider selectConnectionProvider(String tenantIdentifier) 方法,并且必须返回一个 c3p0 ConnectionProvider 对象才能使用。
真正的问题是:当用户 user1 对系统进行身份验证时,db 连接正常。但是当 user2 进行身份验证时,ConnectionProvider selectConnectionProvider(String tenantIdentifier) 方法接收的参数是 user1,而不是 user2,导致我们选择与 user1 相同的数据库。
EntityManager 是使用 PersistenceContextType.EXTENDED 注释实现的,这会导致问题吗?也许它正在重用有关第一个用户的信息!