0

我有一个 JSF 应用程序,其中用户可以通过 loginBean 登录,如下所示:

public String doLogin() {
        Query query = ejbFacade.getEntityManager().createNamedQuery("loginQuery",  User.class);
    query.setParameter("email", username);
    query.setParameter("pw", pw);
    try {

        FacesContext context = FacesContext.getCurrentInstance();
        context.getExternalContext().getSessionMap().put("user", query.getSingleResult());
        return "/loggedin/index?faces-redirect=true";
    } catch (NoResultException userNotFoundEx) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Unknown login, try again"));
        return "/public/login";
    }
}

然后我有一个产生@LoggedIn 用户的userRegistrationBean。这个 bean 是 SessionScoped 所以当一个注册一个已经登录时。要知道用户是来自“直接登录”还是“注册登录”,我执行以下操作:

@Produces @Logado
public User getLoggedUser() {
    if (this.user.getId() == null) { //means no user was registered this time

        this.loggedUser = FacesContext.getCurrentInstance().context.getExternalContext().getSessionMap().get("user");

        if (this.loggedUser != null) {
            return this.loggedUser;
        }

        throw new IllegalStateException("There's no user logged in.");
    }

    this.loggedUser = this.user;
    return this.loggedUser;
}

我的注销方法:

FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "/index.xhtml?faces-redirect=true";

问题是,当我直接进入数据库并更改时,假设某个用户名,然后我使用该登录名进入系统,该名称不是最新的。假设我的数据库是空的。然后我注册一个用户->注销->手动更改数据库中的某些内容->登录该用户。用户数据未更新。似乎该应用程序再也不会从数据库中读取数据,但 Eclipse 链接在每次登录时都会显示一个新查询。有人可以启发我吗?

4

1 回答 1

1

EclipseLink 有一个二级缓存,如果您要在 JPA 之外进行更改,则需要对其进行管理。有关缓存的详细信息在这里:http ://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching

最简单的解决方案是调用 em.refresh(entity) 如果您知道已经进行了更改,但 EclipseLink 也有可以刷新的查询提示。作为一个更极端的选择,您可以禁用共享缓存,但这应该是最后的手段,因为缓存可以提高大多数应用程序的性能。

于 2013-08-26T14:33:36.990 回答