如何在使用JPA加载后更新会话属性

时间:2013-04-14 18:14:15

标签: session servlets jpa-2.0 session-variables

在使用JPA加载一些数据后,我遇到了更新会话属性的问题。

我设置/获取会话属性:

request.getSession().setAttribute("user", user);

User user = (User) request.getSession().getAttribute("user");

在应用程序的某处,我从数据库加载users列表(与会话属性中包含相同的user),修改并保存。一切都会很好,我将获得最新的信息,但如果我从会话属性获得,则不会。 我不想要几乎静态信息的请求数据库,但另一方面我不知道如何更新会话属性。

存储会话属性可能是非常不正确的实现吗?

更新 这个解决方案怎么样:

我有会话属性缓存

public static final HashMap<String, HashMap<String, Object>> sessionAttributeMaps = new HashMap<>(); 

public static final HashMap<String, HashMap<String, Object>> sessionAttributeMapsForUpdate = new HashMap<>();

sessionAttributeMaps我使用HttpSessionAttributeListener存储会话属性(我需要稍后刷新并保持实际状态):

@WebListener
public class SessionAttributeListener implements HttpSessionAttributeListener{

    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        String SessionId = event.getSession().getId();
        String attributeName = event.getName();        
        Object attributeValue = event.getValue();    

        if (attributeName.equalsIgnoreCase("user")) {
            HashMap<String, Object> hm = ServletUtil.sessionAttributeMaps.get(SessionId);
            if (hm==null) {
                hm = new HashMap<String, Object>();
                ServletUtil.sessionAttributeMaps.put(SessionId, hm);
            }
            hm.put("user", attributeValue);
        }
    }
    ...
}

sessionAttributeMaps(用于多个已创建的会话):

[ [会话1:[{“user”:user1},{“customer”:customer1}]],

[会话2:[{“user”:user1},{“customer”:customer2}]],

[会话3:[{“user”:user2},{“customer”:customer1}]] ]

sessionAttributeMapsForUpdate中我存储了会话属性的实际值(当它们被更改时,我在地图中检查它在POJO实体中实现的所有会话)。

public void fireChanges() {    
    for (Entry<String, HashMap<String, Object>> sessionAttributesMap : servlets.ServletUtil.sessionAttributeMaps.entrySet()) {
        for (Entry<String, Object> entry : sessionAttributesMap.getValue().entrySet()) {
            if (this.equals(entry.getValue()) && this!=entry.getValue()) {
                entry.setValue(this);
                HashMap<String, Object> hm = ServletUtil.sessionAttributeMapsForUpdate.get(sessionAttributesMap.getKey());
                if (hm==null) {
                    hm = new HashMap<String, Object>();
                    ServletUtil.sessionAttributeMapsForUpdate.put(sessionAttributesMap.getKey(), hm);
                }
                hm.put("user", this);
            }
        }
    }
}

如果user1发生了变化,请填写sessionAttributeMapsForUpdate

[ [会话1:[{“user”:user1}]],

[会话2:[{“user”:user1}]] ]

在帮助程序中,我获取会话属性并检查更新(使用已更新的清除)

public static Object getSessionAttribute(String key) {

    Object value = FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key);

    if (key.equalsIgnoreCase("user")) {
        if (!ServletUtil.sessionAttributeMapsForUpdate.isEmpty()) {
            HttpSession hs = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
            HashMap<String, Object> hm = ServletUtil.sessionAttributeMapsForUpdate.get(hs.getId());    
            if (hm!=null) {
                User u = (User) hm.get("user");
                if (u!=null) {
                    value = u;
                    removeSessionAttribute("user");
                    setSessionAttribute("user", value);

                    hm.remove("user");
                }
                if (hm.isEmpty()) {
                    ServletUtil.sessionAttributeMapsForUpdate.remove(hs.getId());
                }
            }
        }
    }

return value;
}

警告setSessionAttribute("user", value);无法removeSessionAttribute("user");无效,因为新value等于value from session map(但!=

所以,当我用helper获取session属性时,我会使用实际值。

可能已经有像我这样的解决方案,但经过时间考验?

0 个答案:

没有答案