2016-05-30 20 views
3

内のエンティティに両方の方法を設定する必要があります:は、なぜ私は私は2つの次のエンティティを持っているJPA

@Entity 
public class Pilot implements Serializable { 
.... 
    @ManyToOne 
    @JoinColumn(name = "FLIGHT_ID") 
    private Flight flight; 
} 

@Entity 
public class Flight implements Serializable { 
.... 
    @OneToMany(mappedBy = "flight") 
    private List<Pilot> pilots; 
} 

私は飛行機にパイロットを追加するEJBを使用しています:

public void addPilotToFlight(String pilotId, String flightId) { 
    <code to find Flight f> 
    <code to find Pilot p> 
    p.setFlight(f); 
    f.getPilots().add(p); // Why do I need this one? 
} 

なぜ私はオブジェクトを両方向にリンクする必要がありますか?

f.getPilots().add(p);部分の有無にかかわらずコードを試しましたが、DBではまったく同じように見えます。しかし、同じフライトエンティティオブジェクトに対してf.getPilots();を使用しようとすると、上記の双方向リンクを行った場合にのみ表示されます。誰もがこれについていくつかの光を発することができますか?私はとても感謝しています。前もって感謝します。

答えて

2

よくある質問と混乱の原因である双方向関係の両面を維持しなければならない理由を尋ねるのが目的です。

CMP 2.0はバックグラウンドでの関係維持と魔法を実行しようとしましたが、オーバーヘッドと制御不足が問題でした(JPAには含まれていませんでした)。代わりに、JPAエンティティは、普通の古いJavaオブジェクトであることを意図しています。つまり、関係の片側に加えられた変更を他の側に反映させたい場合は、自分で作成する必要があります。

リレーションシップの一方の側を修正し、他方を修正しないと、データベースが正しく更新されないことがあります。時には両側で変更が表示されることがあります。それは、どちらの側を変更するか、エンティティがデータベースからどのようにキャッシュされ、リフレッシュされるかによって異なります。所有側の変更はデータベースに永続化され、JPAではキャッシングが許可されるため、非所有側ではデータベースからリフレッシュされるまでこれらの変更が反映されないことがあります。

ベストプラクティスは、オブジェクトモデルをデータベースと同期させたままにしておきたい場合は、アプリケーション側で変更を加える必要があります。

+0

キャッシングによってパフォーマンスが向上するアプリケーション全体で処理されてもスケーラビリティは向上しますが、そのコストとドローバックがあります。あなたのエンティティのアクセサメソッドでもう一方の側を簡単に設定できるので、この問題のために私はそれをオフにしません。 – Chris

0

JPAでは「一方向」の関係があるため、 "mapped by"属性を指定しないと、双方向の1:N関係ではなく、2つの一方向関係(1:NとN:1)を作成することはありません。

次に、「なぜ人々は2つの一方向の関係を必要としますか」と尋ねることがあります。そしてその答えは、JPAが奇妙なレガシーデータベースを満足させるために作られたからです。 :-)

+0

エンティティクラスでFlightのPKをどのように定義しているのか、あなたの質問に答えるためにコード内のエンティティにアクセスする方法(エンティティマネージャの作成方法など)を理解する必要があります。 – Leo

関連する問題