2012-12-14 14 views
7

私はレガシーシステムで作業しています。データベースから情報の一部を読み取る必要があります。以下はJPAの非プライマリキー列とのテーブルの結合

ベンダー(ベンダーID - PK、vendorEid、名)テーブル関係ある
VendorContactBridge(bridgeId -pk、vendorEid、contactEid)
連絡先(contactId -pk、contactEid、携帯電話)

vendorEidとcontactEidテーブルの主キーではなく、JoinテーブルのVendorContactBridgeで結合列として使用されます。

ベンダーエンティティ -

@Entity 
@Table(name="Vendor") 
public class Vendor implements Serializable{ 

@Id 
@Column(name="VENDORID") 
private BigDecimal vendorId; 

@Column(name="VENDOREID") 
private BigDecimal vendorEid; 

@OneToMany(fetch = FetchType.EAGER) 
@JoinTable(name="VENDORCONTACTBRIDGE", 
joinColumns={@JoinColumn(name="VENDOREID", referencedColumnName="VENDOREID")}, 
inverseJoinColumns={@JoinColumn(name="CONTACTEID", referencedColumnName="CONTACTEID")}) 
private Set<Contact> vendorContact; 
} 

連絡先エンティティ -

@Entity 
@Table(name="CONTACT") 
public class Contact implements Serializable{ 

@Id 
@Column(name="CONTACTID") 
private BigDecimal contactId; 

@Column(name="CONTATEID") 
private BigDecimal contactEId; 

@ManyToOne 
@JoinTable(name="VENDORCONTACTBRIDGE", 
joinColumns={@JoinColumn(name="CONTACTEID", referencedColumnName="CONTATEID")}, 
inverseJoinColumns={@JoinColumn(name="VENDOREID", referencedColumnName="VENDOREID")}) 
private Vendor vendor; 
} 

クエリを実行中に、例外

下になっSecondaryTable JoinColumnは、非主キーを参照することはできません。

ベンダーエンティティで指定したEagerフェッチを削除しましたが、例外はありませんが、コレクションはロードされません。関連の問題は何ですか?

答えて

10

ページのJPA 2.0 specs段落11.1.21 JoinColumnのannotaionによると379

参照されるテーブルの主キー列ではありません参照される列のサポートはオプションです。このようなマッピングを使用するアプリケーションは移植不可能です。

これはHibernateがこのオプション部分を実装しないことを選択したようです。他の実装が可能性があります。私はEclipseLinkで試してみましたが、どちらもうまく動作しません(検証に失敗します)。

2つの回避策があります。 1つは、データベース設計理論の観点から正しいキーとなる主キーを使用するようにスキーマを調整することです。ただし、このスキーマに応じて、オプション2を残している他のソフトウェアがあるため、これはオプションではない可能性があります。 JPAの関係を改造しないで回避するだけで、eidを使用して、関連するオブジェクトを自分で取り出すことができます。

+0

オプション2:あなたが意味するか、私は連絡先にVendorEidに基づいてVendorContactBridgeからContactEidを取得して、再度のための2デシベルの呼び出しものを作る必要がありContactEidにASED?私の理解は正しいのですか? – Pankaj

+0

これは基本的なプリンシパルになります。しかし、結合を行うことができるようにネイティブクエリを使用し、オブジェクトを取得するために単一のSQLクエリを使用するのが最善の方法です。 – Eelke

関連する問題