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);
newが等しいremoveSessionAttribute("user");
ため、機能しません(ただし)value
value from session map
!=
したがって、ヘルパーでセッション属性を取得するときは、実際の値を使用します。
私のような解決策はすでにあるかもしれませんが、実績はありますか?