2011-12-23 9 views
12

質問には@ManyToMany without join table (legacy database)と同様の問題があり、その他の問題があります。複数列の主キー(IDID3)と多対多の関係を持つ読取り専用データベースを結合テーブルなしでマッピングする

Iが複数列の主キー(IDID2)を持つ2つのテーブルAB

  • Aを有する
  • B

Aの行は、BB.ID = A.ID)、Bの行は、Aの複数行で参照できます。

EDIT:このデータベースは、私が変更できない読み取り専用のレガシーデータベースです。私はJPAとの関係をマップする必要はありません(追加の選択肢を使って自分のプログラムロジックで行うこともできます)が良いでしょう。

基本的には、結合テーブルを使用しない多対多の関係です。リンクされた質問については、テーブルを読むだけで済むので、私は両方のクラスで2対1の関係を試しました。

追加の問題は、結合に使用されるIDの両方が主キーではないということです。

私は次のクラスがあります。B.idAで単一のプロパティを参照している(A.id):私は本当にメッセージを取得しない

Exception while preparing the app : referencedColumnNames(ID) of package.B referencing package.A not mapped to a single property 

@Entity 
@Table(name = "A") 
@IdClass(PrimaryKeysA.class) 
public class A { 

    @Id 
    @Column(name = "ID", insertable = false, updatable = false, columnDefinition = "char") 
    private String id; 

    @Id 
    @Column(name = "ID2", insertable = false, updatable = false) 
    private int id2; 

    @OneToMany(cascade = CascadeType.ALL) 
    @JoinColumn(name = "ID", columnDefinition = "char", referencedColumnName = "ID") 
    private Set<B> setOfBs; 

} 

@Entity 
@Table(name = "B") 
@IdClass(PrimaryKeysB.class) 
public class B { 

    @Id 
    @Column(name = "ID", insertable = false, updatable = false, columnDefinition = "char") 
    private String id; 

    @Id 
    @Column(name = "ID3", insertable = false, updatable = false) 
    private int id3; 

    @OneToMany(cascade = CascadeType.ALL) 
    @JoinColumn(name = "ID", columnDefinition = "char", referencedColumnName = "ID") 
    private Set<A> setOfAs; 

} 

Hibernateは次のエラーが発生します。

EDIT:要求としては:

public class PrimaryKeysA implements Serializable { 

private static final long serialVersionUID = 1L; 

private int id1; 
private int id2; 

    // getters/setters/equals/hashcode 

} 

PrimaryKeysB ID3の代わりID2と同様です。 ABの両方のクラスは、簡略化された(匿名化された)例です。

+1

これらのテーブルで多対多を使用する方法は実際にはわかりません。 A.IDはB.IDを参照し、B.IDはBの主キーです。 AからBへのManyToOneの関連付けがあります。 –

+0

Ooopsは申し訳ありません。私はBと同じAを持っています。私は質問を編集します(私は単純化した例も生成しようとしましたfar) – Matteo

+0

これは2つのテーブル間の多対多の関連ではありません...なぜ各テーブルで2つのIDを使用していますか?このスキーマをより標準的な形式に変更できますか、これは従来のデータベースですか?レガシーデータベースでない場合は、多対多の関連付けが必要な場合は、結合テーブルを使用しない理由は何ですか? –

答えて

4

あなたは、テーブルを結合として作用するビューを作成できます。

CREATE VIEW AJOINB AS 
SELECT A.ID as AID, A.ID2 as AID2, B.ID as BID, B.ID3 as BID3 
FROM A JOIN B ON A.ID = B.ID 

をそして結合テーブルとしてAJOINBと多対多としてJPAでそれをマッピングします。

A.ID2とB.ID3がそれ自身でユニークだった場合は、JPA BeanにA.IDとB.IDをマップする必要はありません。

+0

DBは読み取り専用なので、すべてのテーブルのコピーと追加のビューを持つ新しいDBを作成する必要があります。 DB上に2つのエンティティを定義し、別のエンティティに結合テーブルを定義できるとは思わない)。追加のDBを使用しなければならない場合、私はより良い方法でデータをリファクタリングしようとします。しかし、価値があるかもしれません... – Matteo

+0

あなたのDBによって異なります。 OracleおよびSQL Serverでは、テーブルのエイリアスを使用できます。また、スキーム間のビューを作成することはMySQLでも可能です。 – greyfairer

+0

はい別のスキーマでビューを作成することは問題ありません。 1つのスキーマのエンティティを別のスキーマ内の結合テーブルで定義すると機能しないことが懸念されます(私はチェックしませんでした)。しかし、DB(スキーマだけでなく)は読み取り専用であるため、DBリンクを使用する必要があります。他のアクセス権はありません。 – Matteo

2

テーブルからいくつかのサンプルレコードを共有できますか?

問題は非常に明確です。 1対多の関係の場合、「1」側では、一意に識別できるレコードは1つだけです。ここでは、idは一意ではないので、複数のエントリがあると思います。

@ JoinColumnsを使用して、両方の列を追加して、「1」側のエンティティを一意に識別することができます。

@OneToMany 
@JoinColumns({ 
    @JoinColumn(name="yourID1", referencedColumnName="yourID1"), 
    @JoinColumn(name="yourid2", referencedColumnName="yourid2") 
}) 

次のデータがあるとします。

テーブルA:

id2 c1   id 
100 content1 1000 
101 content2 1001 

テーブルB:

id3 s1   id 
100 content1 1000 
101 content2 1000 
102 content3 1001 
103 content4 1001 

ここでID2とID3ユニークです。 A.idはユニークですが、b.idはユニークではありません。典型的なOneToManyシナリオです。

IはA.idとB.idを使用してBにマッピングする場合、これは1対多数となるIDが1000

そのままA(100)B(100、101)を参照することができる場合これはうまくいくと思います。しかし、同じ列(質問に記載されている)を使用してBからAにマッピングする必要がある場合、片面(B)に重複があるため機能しません。

質問を正しく理解していますか?

+0

ところで、私は答えとして何かを投稿せずにこれをコメントとして追加する方法はわかりません。誰か助けてくれますか? –

+0

Hibernateは多くの面で不平を言っています。私はB.id1を参照しているA.id1を持っています。 B.id1はユニークではありません(1対多数)。 HibernateはB.id1がプライマリキーの一部であることを私に伝えますが、誰が気にします。 A.id1ごとに、より多くのB.id1があります。 B.id1がBの主キーの**部分**である場合、関連性はないはずです。テーブルはid1のみに関連しています(id2はBには存在しません)。 – Matteo

+0

コメントするには50の評判が必要です – Matteo