2011-08-12 24 views
1

私はJPAに慣れていませんが、このシナリオがあります:KISS/DRYの理由で、サーバーとクライアント(Java SE)の両方で同じクラス(「コード」を読む)を使用したいと考えています。これを行う可能性のある方法の1つは、エンティティへのリクエストをサーバーに渡し、最後にすべてのエンティティをサーバーに戻して「バッチ・パーシスト・アクション」を送信する(特殊な)EntityManagerをクライアント上に持つことです。クラスがデータの検証(再検証)、トランザクション操作(更新と処理)を適用し、すべてJPA実装によってうまく維持される場所。リモート管理されたエンティティを持つことは可能ですか?

質問は:それは可能ですか?どうやって? (?このためのソリューションがすでにあり、それは「一部」のコードでこれを解決するために、一種の、シンプルなのですか?)


編集: [OK]を、私はみんなのために物事のカップルを明確にしましょう。私の背景は、ジェネリック・パーシスタンス・サービスと呼ばれることがあるものを使用する社内で成長したアプリケーション・フレームワークです。単一のトランザクション内でCRUDアクション(テーブル内のアクションごとに1つのサービス)を実行するサービスですが、これらのアクションをインターセプトし、検証と(しばしば)複雑なビジネスルール(他のテーブル、等。)。これは古いMicrosoft製品で実装されました。 DevForceやCSLAのような、以前は類似しているが高度なフレームワークが登場した.NETへの移行があります。 DevForceは、特に私がJavaでやりたいことを提供しています(詳細については、this pageの「クライアントで実行する」の段落を参照してからthis pageを参照してください)。

この一般的なテーマに関する私の古い質問:Java "equivalent" to CSLA

+1

デタッチされたエンティティをクライアントに送信して変更し、再接続と永続性のためにサーバーに戻す方法とはどのように違いますか? –

+0

@edalorzoそれは私が言っていることですが、... "経営"がキーワードです。私のクラスはJPA対応であるため、クライアント上にEntityManagerを持っていて、私が作業していたエンティティをすべて「パックアップ」して送ることができますか? 1つのトランザクション・スワップで永続性を適切に処理できる一部のサーバー上のEntityManager? – Doc

+0

私はまだあなたのシナリオを理解しているとは思わない。私の見解では、クライアントはエンティティマネージャーのようなものが存在することを知るべきではありません。ビジネスインタフェースを介して正しく公開されているため、クライアントから要求されたときに単一のトランザクションスウォープで提案したすべての作業を実行することができ、エンティティはサーバーの安全性を放棄することもありません。同時性に関しては、クライアントごとに永続コンテキストを持つことは悪夢である必要があります。並行性のレベルによっては、すべてのクライアントが非常に短時間で無効なキャッシュになる可能性があります。あなたは思いませんか? –

答えて

0

あなたのアイデアがスマートです。

しかし、あなたの提案をすることはできません。それはなぜですか?さて、これに答えるには、まず「管理対象とは何か」を理解しなければなりません。

管理対象エンティティは、「キャッシュされた」インスタンスではありません。エンティティマネージャ内に存在するインスタンス。このインスタンスをネットワーク経由で別のマシンに送信する場合は、をコピーしてとします。リモート・サーバ上に別のインスタンスを作成することはもちろんです(エンティティ・マネージャは、存在)。

もう一方の側では、エンティティマネージャをシミュレートし、このコピーされたエンティティを「管理」するために「十分にスマート」なものが存在する可能性がありますが、これはJPA仕様から外れています。簡単だと思われる)。私はそこに信頼できるものが存在するとは思わない。

解決策は、クライアントから明示的に(サーバーから公開されたメソッドを通じて)永続化、更新などを行うことです。

+0

つまり、サーバー上のEntityManagerの重要なメソッドをクライアントに公開する必要がありますか?取引はどうですか?私は、トランザクションを自分で制御しなければならないという事例を見てきました。つまり、トランザクションを開始し、自分のことを行い、トランザクションをコミットします。私は自分のものをしたいと思いますし、EntityManagerにトランザクションの永続性に必要なことを自動的に行うように指示します。 – Doc

+0

これを行う方法は、1トランザクションで実行するサーバーから「ビジネスサービス」(たとえば:placeBid)を公開し、ユーザーの「画面フロー」が終了したときに呼び出すことです。クライアントからオープンされたトランザクションを維持する(可能な場合)ことは、通常はお勧めできません。いくつかのサービスコールにまたがるクライアントから開かれたトランザクションを維持することは可能ですが、救済なしにネットワーク経由で送信された場合、エンティティは常に切り離されます。 – edutesoy

1

私は私はあなたが理論的に作品を何を考えていると信じて

(私はWSのためにその時間を休止+のXFireを使用していた)の前に同様のことを行うと、おそらくちょうど私の知見にビットを共有しようとしています。あなたがしなければならないことは、管理されたエンティティをシリアライズしてクライアントに送信することです。クライアントはオブジェクトを逆シリアル化して更新します(もちろん、クライアント側では管理されていないエンティティではない通常のPOJOです)。この時点で、サーバーによって受信されたオブジェクトは単なる切り離されたオブジェクトです。あなたはセッションに再接続することができます(JPA/Hibernateはそれらのオプティミスティック並行性チェックを行います)。

しかし、それは非常に単純にPOJOでうまく動作します。主要な問題の1つは、JPA(または主にすべてのORMフレームワーク)において、異なるエンティティ間の関係を持つことです。例えば、OrderはProductとAccountとの関係を持ち、AccountはClientとのRelatinshipsを持ち、ClientはAddressesのリストを持ちます。それは、レイジーフェッチや関係のためにサーバ側で操作していると大抵は問題ありませんあなたがそれにアクセスするまで、実際にはフェッチされません。ただし、シリアライゼーションを実行すると、解決するのが難しい問題になります.JAXBのようなほとんどのシリアル化ソリューションは、すべてのプロパティを再帰的にナビゲートします。その結果、Orderオブジェクトだけをクライアント側に送信することになりますが、最終的には、大量のデータをClientに送信しています。シリアライザにいくつかのプロパティをシリアライズしないように指示するだけでは、オブジェクトが返されたときにcozしてセッションにデタッチされたobjを再接続することはありません。JPA/Hibernateは、単に関係を無視するか、関係を削除する。もちろん、あなたができるトリックはまだありますが、これらはすべてこのようなアプローチを採用するのに苦労し、もはやエレガントではありません。

+0

共有ありがとうございます – Doc

関連する問題