11

私は自分の質問をして答えていますが、私が最良の答えを持っているとは思いません。より良いものがあれば、投稿してください!

関連する質問:

単純な集約関係にあるクラスのペアがあります。一方のインスタンスは、もう一方のインスタンスをいくつか所有しています。所有するクラスには、それ自体のある種の主キーがあり、所有するクラスには、対応する外部キーを介してこのクラスに対して多対1があります。所有するクラスに、その外部キーといくつかの追加情報で構成される主キーを持たせたいです。

議論のために、それらの長年のお気に入りであるOrderとOrderLineを使用しましょう。

SQLは次のようになります。

-- 'order' may have been a poor choice of name, given that it's an SQL keyword!
create table Order_ (
    orderId integer primary key
);
create table OrderLine (
    orderId integer not null references Order_,
    lineNo integer not null,
    primary key (orderId, lineNo)
);

これをJPAを使用してJavaにマッピングしたいと思います。順序は簡単で、OrderLineは@IdClassで処理できます。これがそのためのコードです-コードはかなり慣習的です、そしてあなたが私の特異性を許してくれることを願っています。

ただし、@ IdClassを使用するには、OrderLineのフィールドを複製するIDクラスを作成する必要があります。その重複を避けたいので、代わりに@EmbeddedIdを使用したいと思います。

ただし、これを行うための素朴な試みは失敗します。

@Embeddable
public class OrderLineKey {
    @ManyToOne
    private Order order;
    private int lineNo;
}

OpenJPAは、@EmbeddedIdとしての使用を拒否します。私は他のプロバイダーを試したことがありませんが、JPA仕様では、IDクラスを構成するフィールドが関係ではなく基本である必要があるため、それらが成功することは期待できません。

それで、なにかお手伝いできますか?キーに@ManyToOne関係が含まれているが、@ EmbeddedIdとして処理されるクラスを作成するにはどうすればよいですか?

4

1 に答える 1

19

フィールドの複製を伴わないこれを行う方法がわかりません(申し訳ありません!)。ただし、関係フィールドのみを複製するという、単純で標準的な方法で実行できます。重要なのは、JPA2で導入された@MapsIdアノテーションです。

埋め込み可能なキークラスは次のようになります。

@Embeddable
public class OrderLineKey {
    private int orderId;
    private int lineNo;
}

また、埋め込みエンティティクラスは次のようになります。

@Entity
public class OrderLine{
    @EmbeddedId
    private OrderLineKey id;

    @ManyToOne
    @MapsId("orderId")
    private Order order;
}

@MapsIdアノテーションは、それが適用されるリレーションシップフィールドが、埋め込まれたIDから基本フィールドを効果的に再マップすることを宣言します。

OrderIdのコードは次のとおりです。

于 2011-08-25T19:37:06.727 に答える