0

jpa を使用しているときに気付いた奇妙なことを次に示します。私はopenjpa 1.0、RAD 8.0、およびWAS 6.1を使用しています(jpa 2は使用できません)。

クラス ProductArrangement があり、そのクラス内にアカウントのリストがあります。アカウント内にステートメントのリストがあります。最初のアカウントと最初のステートメントを使用して最初の productArrangement を作成すると、永続化は問題なく機能します。すべてが適切に DB に格納されます。

後で、find でアクセスした productArrangement のアカウントにステートメントを追加したい場合、アカウントまたはステートメントに永続化の結果がありませんでした。productArrangement の変更は成功しました。ただし、 getAccount().addStatement(statement) の前に getAccount().getStatements() を実行すると、正常に動作します。これはどのように可能ですか?get before を実行しなければならないのは、遅延フェッチのためですか?

4

1 に答える 1

0

> get before をしなければならないのは、遅延フェッチのためですか?

エラー... はい、いいえ。
はい: 遅延ロードが行われていないようで、バグがあります。
いいえ: プロバイダー コードのバグではない可能性がありますが、 および のコードのバグである可能性がありaddAccount()ますaddStatement()

新しいアカウントまたはステートメントを追加することは、これらのエンティティのコレクションへの関係をナビゲートすることを意味する必要があります。遅延ロードが自動的にトリガーされるはずなので、これがエラーの原因になることはありません。

ただし、 getter メソッドを呼び出してエンティティ内から遅延読み込みを自動的にトリガーすることにより、関係をナビゲートする必要があります。エンティティ内のインスタンス フィールドに直接アクセスしても、遅延読み込みがトリガーされることはありません。これは、JPA プロバイダーではなく、コードのバグです。

> しかし、getAccount().addStatement(statement) の前に getAccount().getStatements() を実行すると、正常に動作します。

たぶんあなたの方法は次のようになります:

 public class Account {

     // fields and methods ...

     public void addStatement(Statement s) {
          this.statementsCollection.add(s);
     }
 }          

もしそうなら、それは遅延読み込みのバグです。次のようになります。

 public class Account {

     // fields and methods ...

     public void addStatement(Statement s) {
          this.getStatements().add(s);
     }
 }          

つまり、addStatement の内部コードが自動的に行うため、外部のクライアント/テスト コードで人為的に getAccount().getStatements() を呼び出す必要はありません。

:-D

于 2012-10-16T07:01:01.570 に答える