我在GAE / J中有一个非常奇怪的问题。事情在本地环境中起作用,但在GAE服务器上不起作用。
环境:GAE / J 1.8.2 + JSF 2.2.1 + JPA
我有一个由JPA管理的对象 - 让我们称之为X(实现Serializable) 我有一个限定为会话映射的bean - 让我们称之为Y(实现Serializable)
我的班级Y如下所示。
@SessionScoped
class Y implements Serializable
{
private X selectedObject;
// Getter & setter for X
}
作为操作的一部分,我设置X的值,然后将用户重定向到另一个页面。当我在第二页中访问bean时,它告诉我没有为X设置任何值。
现在,我的猜测是由于某种原因,GAE没有在数据存储区支持的会话中将此引用存储到X.我尝试了各种日志记录,但我无法弄清楚为什么只有X(一个JPA实体)没有与对象的其余部分一起持久化到会话范围。
这里可能出现什么问题的想法?
谢谢, 戒日
答案 0 :(得分:0)
发现了这个问题。所以我知道为了避免ViewExpiredException,其中一种方法是设置一个阶段监听器,它将随机属性更新到会话映射中,从而强制将映射序列化到数据存储。我做的一个错误就是让这个阶段监听器在RENDER_RESPONSE阶段的afterPhase()中完成这项工作。
我忘记考虑的事实是在INVOKE_APPLICATION阶段发生了面部重定向...这意味着我的侦听器从未在重定向情况下被调用。
将侦听器更改为ANY_PHASE并显式更新INVOKE_APPLICATION或RENDER_RESPONSE的会话映射后,我现在看到了预期的结果。
示例代码供您参考。
public class SessionSerializationListener implements PhaseListener
{
@Override
public void afterPhase(PhaseEvent event)
{
// Set an attribute on to the session just so that we can force the session to get serialized
// We target the invoke application phase as well since the redirects get issued in that phase
if (event.getPhaseId() == PhaseId.INVOKE_APPLICATION || event.getPhaseId() == PhaseId.RENDER_RESPONSE)
{
// get hold of the session map
sessionMap.put("__timestamp__", System.currentTimeMillis());
}
}
@Override
public void beforePhase(PhaseEvent event)
{
// Do nothing.
}
@Override
public PhaseId getPhaseId()
{
return PhaseId.ANY_PHASE;
}
}