DWR2のscope=sessionは不変オブジェクト??

前回のログで取り上げたサンプルなのだが、実は、Google Apps Engine上ではうまく動かない。
People.javaクラスをsessionスコープに定義しているのだが、レコードを削除して、画面をリフレッシュすると、初期状態に戻ってしまう。

これを、そのまま開発環境でTomcat6.0に置くと、セッションを保持している限り、削除したレコードはリフレッシュしても消えたままとなる。

あちこちいじってみたが、どうも、GAE上のDWRでは(dwr.xmlでscope=sessionと定義する)People.javaの「メンバー変数の更新」が行われないようである。

DWRのHPをひっくり返してみると、次のような記述があった。
ページ最後のくだり。

One subtlety about the way the DWR 1.x stores created beans is that it re-calls the corresponding setAttribute() method for every request. That is, if your bean has been given session lifetime in dwr.xml, session.setAttribute(yourBean) will be invoked everytime you invoke a method on that bean.
・・・
DWR 2 only calls setAttribute() when it first creates the object.(上のHPより引用)

… DWR1.xだと、セッションの生存期間内で、全てのリクエストに対してsetAttribute()を呼び出していたが、DWR2だと、setAttributeはオブジェクトが最初に生成されたときに限るようになった。


以前のサンプルで示したとおり、GAE上でも、Sessionオブジェクトにいれた要素を取り出し、更新した後にsetAttribute()すれば、キッチリ永続化、更新、復元ができる。

この下りを読む限り、DWR1ではそうだったが、DWR2ではそうではない、と読める気がする。

とすれば、(Tomcatの挙動はともかくとして)DWR2でセッションスコープのbeanを定義する場合、それは「不変オブジェクト」にした方がよい(DWR2はそういう風に設計されている)、と解釈できる。
シリアライズするオブジェクトは、そもそも不変オブジェクトにすべき、という議論もあるし)

DWRを使うようなアプリでも、

  • 認証情報
  • ショッピングカートのような情報

は、セッションスコープで保持しておきたいだろう。前者は、不変オブジェクトでいいかもしれないが、後者にはなんらか工夫をしないといけない。