【问题标题】:Multi Tenant resolving to wrong tenant identifier EJB + JPA + HIBERNATE多租户解析为错误的租户标识符 EJB + JPA + HIBERNATE
【发布时间】:2012-09-24 16:12:05
【问题描述】:

我在使用 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 注释实现的,这是导致问题的原因吗?也许它正在重用有关第一个用户的信息!

【问题讨论】:

    标签: hibernate jpa ejb entitymanager multi-tenant


    【解决方案1】:

    根据各种帖子,对有状态 bean 的 JNDI 查找可以创建 bean 的新实例。相反,为调用resolveCurrentTenantIdentifier() 返回相同的bean。请检查服务定位器和 JNDI 查找方法。 JNDI 库缓存对象实例是一种常见的行为。由于您已调用 JNDI 查找对应于 user1 的 SessionEjbContext,它可能已被缓存并为所有后续调用返回。

    【讨论】:

      猜你喜欢
      • 2023-03-07
      • 2012-05-29
      • 2019-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      • 2018-02-06
      • 1970-01-01
      相关资源
      最近更新 更多