1

Spring MVC + Hibernate を使用した単純な Web アプリケーションがあり、OpenSessionInViewFilter を使用しています。最近、UI を Flex や GWT のようなものに置き換えようと考えています。

最初は、新しいフロント エンドからサービス レイヤーにアクセスするだけでよいので、簡単だと思いました。しかし、これをもう少し考えてみると、遅延読み込みを取り巻く問題について少し神経質になっています。ビューで開いているセッションを使用しているため、従来のWebフロントエンドを使用しても問題ありません...ビューのためにロードする必要があるすべてのものは、ビューが構築されるときにロードされます。

では、Customer を返すメソッドがあり、Customer には多数の連絡先があり、Contacts には多数の Address があるとします。新しい「RIA」コントローラーから getCustomer() を呼び出すと、Customer が取得されますが、Customer の Contacts コレクションはプロキシまたは null になります。

事前に入力された DTO を返す新しいレイヤーを既に持っているものの上に作成することもできます...しかし...それは複雑になるようです。

何かアドバイス?

4

2 に答える 2

2

これがRIAに問題をもたらすことは間違いありません。OpenSessionInViewFilterを使用している場合、データはnullを返しません。むしろ、シリアライザーはオブジェクトグラフ全体をウォークし、膨大な量のデータを送り返します。これにより、深刻なパフォーマンスの問題が発生します。

別のDTOレイヤーを導入すると、シリアライザーが作成したオブジェクトのみをウォークするようにできるという点で、多くの制御が可能になります。怠惰なプロキシが含まれていないことを確認できます。残念ながら、これにより、エンティティとDTOの間にマッピングコードを記述するのに面倒な作業が発生しますが、必要なことをすべて実行するための完全な制御が可能になります。

もう1つのアプローチは、シリアル化のためにオブジェクトグラフを準備するシリアライザーの直前にレイヤーを導入することです。過去のいくつかのプロジェクトで使用したアプローチの1つは、オブジェクトグラフ全体をウォークし、レイジープロキシを@Idプロパティのみが設定されたエンティティの新しいインスタンスに置き換えるアスペクトをサービスレイヤーに導入することでした。グラフが後で保存された場合、これにより、@ManyToOne関係が誤って無効にされないようになります。getterを呼び出すか、Hibernate.initialize()を使用して、ネットワーク経由で送信したいデータの初期化を強制することができます。Hibernateで@OneToManyまたは@ManyToMany関係のカスケード保存を導入すると、これはさらに複雑になります。

私は最近、この問題を処理するように設計されたギレアデと呼ばれるソルチンに出くわしました。上記と同様のアプローチを使用します。

http://noon.gilead.free.fr/gilead/

また、Granite DSには、Tideフレームワークの一部としてこの問題に対する解決策があると思います。

http://www.graniteds.org/confluence/display/DOC/4.+Lazy+Initialization

誰も解決していないと思う問題の1つは、サーバーからRIAにデータを実際に遅延ロードする方法です。確かにできると思いますが、ここにはセキュリティ上の懸念がいくつかあります。データを遅延ロードしようとする試みが、最初にそのデータをロードする権限を実際に持っているユーザーからのものであることを確認するには、かなり堅牢なセキュリティチェックを実施する必要があります。

于 2009-06-06T17:23:43.753 に答える
0

プレゼンテーション層が顧客の連絡先の存在を必要とする場合、データ層がそれを提供します。遅延読み込みの目的は、データを省略することではありません...コンピュータープログラミングで、必要になるまでオブジェクトの初期化を延期するために使用されます。

心配する必要はありません。

于 2009-06-06T00:17:19.110 に答える