5

JPAのドキュメントとさまざまな投稿を検索した後、JPA2.0で次のことが可能かどうかについて混乱しています。私はJPAを始めたばかりなので、ばかげたことをしていたらすみません。

私のドメイン モデルには、0 個以上の「オープン ポジション」を含む「ポートフォリオ」があります。ポジションは「インストゥルメント」(JPA エンティティ) と価格 (ダブル) で構成されます。ポートフォリオは以下の通りです。

@Entity (name = "portfolio")
public class Portfolio {
    @Id
    @Column (name = "id")
    @GeneratedValue
    private long id;

    @ElementCollection (fetch = FetchType.EAGER)
    @CollectionTable (name = "portfolio_entry", joinColumns = @JoinColumn (name = "portfolio_id"))
    private final Map<Instrument, OpenPosition> positions = new HashMap<Instrument, OpenPosition>();
....

OpenPosition Embeddable は次のとおりです。

@Embeddable
public class OpenPosition extends Position {
    @ManyToOne (targetEntity = InstrumentImpl.class, optional = false)
    @JoinColumn (name = "instrument_id", nullable = false)
    protected Instrument instrument;

    @Column (name = "price", nullable = false)
    protected double price;
....

Instrument エンティティは次のとおりです。

@Entity (name="instrument")
public class Instrument {
    @Id
    @Column(name = "id")
    @GeneratedValue
    private long id;

    @Column(name = "isin", nullable = false)
    private String isin;
....    
    @Override 
    public int hashCode() {
        int hash = 17;
        hash = 31 * hash + isin.hashCode();
    ....

これを使用しようとすると、スキーマが作成され、ポートフォリオを永続化できますが、それらを取得しようとすると、Instrument クラスの hashCode メソッドで NullPointerException が発生します。JPA はハッシュ コードを取得して Map キーを作成しようとしているようですが、Instrument オブジェクトが読み込まれていません。

ID が Instrument オブジェクトに設定されているにもかかわらず、他のすべてのフィールドが null であることをデバッグで確認できます。

私の質問は、キーが Embeddable 値のフィールドとしても存在するエンティティである ElementCollection を JPA2.0 が許可するかどうかです。もしそうなら、私は何を台無しにしていますか。そうでない場合、代わりに Instrument エンティティの ID をキーとして使用するための最善の回避策はありますか?

前もって感謝します。

ps hibernate 4.1.4 JPA実装を使用しています。

4

1 に答える 1

4

私の質問は、キーが Embeddable 値のフィールドとしても存在するエンティティである ElementCollection を JPA2.0 が許可するかどうかです。

はい、私はこのマッピングでそれを行うことができました:

@ElementCollection( targetClass = FreightBid.class )
@MapKeyJoinColumn( name = "carrier_id", referencedColumnName = "id" )
@CollectionTable( name = "freight_bid",
    joinColumns = @JoinColumn( name = "offer_pool_id" ) )
@Access( AccessType.FIELD )
private Map<Carrier,FreightBid> bidsByCarrier;

私の場合、Carrier は で@Entity、FreightBid は@Embedded

このマップを含むエンティティを正しく保持して取得することができました。

私は何を台無しにしています。

protected Instrument instrument;クラスからフィールドを削除し、OpenPosition代わりに Portfolio クラスのマップ フィールドの注釈@MapKeyJoinColumnを使用して、どの列をマップ キーへの結合列として使用するかを宣言する必要があります。

また、マップキーとして機能するオブジェクトの hashCode メソッドで id 以外のフィールドを使用しないようにすることをお勧めします... JPA 実装者は、物事を台無しにする可能性があります。

于 2016-12-01T18:01:19.747 に答える