0

私は GAE/J で非常に奇妙な問題を抱えています。ローカル環境では動作しますが、GAE サーバーでは動作しません。

環境: GAE/J 1.8.2 + JSF 2.2.1 + JPA

JPA によって管理されるオブジェクトがあります - これを X (Serializable を実装) と呼びましょう。

私のクラス Y は次のようになります。

@SessionScoped
class Y implements Serializable
{
  private X selectedObject;

  // Getter & setter for X
}

操作の一環として、X の値を設定し、ユーザーを別のページにリダイレクトします。2 ページ目の Bean にアクセスすると、X に値が設定されていないことがわかります。

さて、私の推測では、何らかの理由で、GAE がこの X への参照をデータストアに基づくセッションに格納していないのでしょう。さまざまなロギングを試みましたが、X (JPA エンティティ) だけが残りのオブジェクトと共にセッション スコープに永続化されていない理由を理解できません。

ここで何がうまくいかないのかについてのアイデアはありますか?

ありがとう、ハルシャ

4

1 に答える 1

0

問題が見つかりました。したがって、ViewExpiredException を回避する方法の 1 つは、ランダムな属性をセッション マップに更新するフェーズ リスナーをセットアップして、マップをデータ ストアに強制的にシリアル化することです。私が犯した間違いの 1 つは、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;
    }
}
于 2013-08-06T20:25:50.803 に答える