0

Java でのオブジェクトのフェッチに問題があります。Entity Bean クラスであるオブジェクト A があり、オブジェクト B (別の Entity Bean クラス) がフィールドとして含まれています。オブジェクト A は B なしで作成され、後でオブジェクト B が何らかのアクションで A にアタッチされました。
問題は、一部のユーザーがオブジェクト A のオブジェクト B を表示できないことです。オブジェクト B は null のように見えます。データベースではすべて問題なく、しばらくするとオブジェクト A が正常に見えます (B を含む)。これは一部のケースでのみ発生し、他のオブジェクトでは最初から適切に見えます。
アプリケーションを実行するために2つの仮想マシンを使用していると言いたいです(おそらく問題になる可能性があります)およびOracle Application Server。
何か助けはありますか?
ストヤン

コードは次のようになります:
エンティティ クラス A は次のように定義されます (B もエンティティ クラス)。

 @Entity
 @Table(name = "A")
 public class A{
     ...
     @ManyToOne
     @JoinColumn(name="ID_B", referencedColumnName="ID")
     private B b;
     ...
 }

クラス A のオブジェクトは、次のようなアクションで作成されます。

public createA_action(){
     A a = new A();
     saveObject(a);
}

ここで、「saveObject」は、データベース内のオブジェクトを永続化またはマージするメソッドです。

後で、次のように他のメソッドが呼び出されます。

public addBtoA_action(){
     A a = getA();
     B b = getB();
     a.setB(b);
     saveObject(a);
}

getA() と getB() は既存のオブジェクトを取得します。

4

2 に答える 2

0

それぞれの entityManager (休止状態のセッション) には、エンティティの独自のメモリ内インスタンスがあります。通常、トランザクションごとに 1 つの EntityManager と、http リクエストごとに 1 つのトランザクションがあります。

したがって、1 つのエンティティ インスタンスが特定のトランザクション t1 で読み込まれ、次に別のトランザクション t2 で読み込まれた場合、t1 でこのエンティティに「a」フィールドを設定すると、t1 がcommited * EntityManager.refresh() メソッドが特定のエンティティで呼び出されます。

* JPA のトランザクション分離レベルは read_commited です

于 2013-05-14T21:28:29.580 に答える
0

問題を解決しました。
前に言ったように、私は 2 つの仮想マシンを使用しています。Gab が前に言ったように、すべての仮想マシンには独自のキャッシュがあります。
シナリオ: user1 は仮想マシン 1 (VM1) を使用しており、もう 1 人のユーザー (user2) は VM2 を使用しており、どちらも作成されたオブジェクトを表示します (最初のトランザクションの後)。その後、user1 がオブジェクトを変更します (2 番目のトランザクション)。VM2 のキャッシュには古いオブジェクトがあるため、User2 にはその変更が表示されません。
解決策: NativeQuery を使用してデータベースから ID を取得し、ID でオブジェクトを取得するメソッドを使用しています。データベースからオブジェクトを取得したメソッドに EntityManager.refresh() を配置すると、すべて正常に動作します。
したがって、変更前に、次のようなメソッドで ID からオブジェクトを取得しました。

public Object getObj(Long id, Class class){
    return em.find(class, id);
}

変更後、このメソッドは次のようになります。

public Object getObj(Long id, Class class){
    Object obj = em.find(class, id);
    em.refresh(obj);
    return obj;
}
于 2013-05-16T12:35:35.633 に答える