2012-04-22 5 views
2

私たちは他のアプリケーションからインポートしたいくつかの読み取り専用テーブルの上にJPAマッピングを作成しようとしています。これらは100億分の1つの行テーブルであるため、スキーマの変更はオプションではありません。 1つのテーブル、つまりOBJECT_ID値を持つMessageテーブルと、任意のOBJECT_IDに関連付けられたENTITY_IDの多数の行を持つDistributionGroupテーブルがあります。次のように、関連するテーブル定義は以下のとおりです。JPA Unidrectional OneToMany via JoinColumn同じレコードをn個のDistinctレコードの代わりに返す

CREATE TABLE Message (
OBJ_ID varchar(255) NOT NULL, 
FileName varchar(255) NOT NULL, 
KEY FileName (FileName)) ENGINE=InnoDB; 

CREATE TABLE DistributionGroup (
OBJ_ID varchar(255) NOT NULL, 
ENTITY_ID varchar(255) NOT NULL, 
KEY OBJ_ID (OBJ_ID)) ENGINE=InnoDB; 

をこれら二つのリンクするJPAマッピング:我々はいくつかのコードを実行しているとき

public class MessageRecord { 
    private String obj_id; 
    private String file; 
    private List<DGRecord> list = new ArrayList<DGRecord>(); 

    @Id 
    @Column(name = "OBJ_ID", nullable = false) 
    public String getObjID() { return obj_id; } 
    public void setObjID (String obj_id) { this.obj_id = obj_id; } 
    //... (Similar for FileName) 

    @OneToMany 
    @JoinColumn(name="OBJ_ID", referencedColumnName="OBJ_ID") 
    public List<DGRecord> getDGRecordList() { return list; } 
    public void setDGRecordList(List<DGRecord> list) { this.list = list; } 
} 

public class DGRecord { 
    private String obj_id; 
    private String entity_id; 

    @Id 
    @Column(name = "OBJ_ID", nullable = false) 
    public String getObjID() { return obj_id; } 
    public void setObjID (String obj_id) { this.obj_id = obj_id; } 

    @Column(name = "ENTITY_ID", nullable = false) 
    public String getEntityId() { return entity_id; } 
    public void setEntityId (String entity_id) { this.entity_id = entity_id; } 
} 

は今、奇妙なビットはすべてを反復処理するために起こります与えられたMessageRecordためDGRecords:

MessageRecord record = [obtained earlier]; 
for (DGRecord dg : record.getDGRecordList()) { 
    System.out.println(dg.getEntityId()); 
    //Do some work with the ENTITY_ID 
} 

私は、データベースに対して手動でこの操作を実行すると、私は私が見て期待していものを手に入れる:

SELECT * FROM DistributionGroup WHERE OBJ_ID = 'ArbitraryObjID'; 
OBJ_ID, ENTITY_ID 
ArbitraryObjID, EntityID1 
ArbitraryObjID, EntityID2 
ArbitraryObjID, EntityID3 

しかしrecordが同じArbitraryObjIDを有する場合に、実際のコードの出力は、次のとおりです。任意の組み合わせについて

EntityID1 
EntityID1 
EntityID1 

、それは、n個の異なるDGRecordsを返すが、同じDGRecord値n回いませんnは問合せを手動で実行して戻される個別の行の数です。私はこれが関連しているかどうかは分かりませんが、実際に同じオブジェクトに対してn回ループしています(同じ[email protected]をn回返すSystem.out.println(dg)の証拠)。

私たちは間違って何をしていますか?それをどうすれば解決できますか?テーブルスキーマの変更やジョインテーブルの追加は非常にコストがかかり、事実上不可能です。しかし、それは人間として十分に機能するので、現在のセットアップを考えれば、これはまだ動作するはずです。

+0

''、あなたのマッピングが間違っていると思うが、いくつかのクエリを使用していることでしょうか? –

+0

うん。それには多くのロジックが組み込まれていますが、理想的にはFileNameのMessageテーブルを照会して1つの結果を取得します。あるいは、単一の有効なMessageRecordで終わるような作業をしてください。私が記述している状況で、MessageRecord.getObjIDがArbitraryObjIDと一致していることを確認しました。 –

答えて

0

私は、[以前の取得]

試して、

@JoinColumn(name="OBJ_ID", referencedColumnName="ENTITY_ID") 
+0

いいえ、間違いなく、MessageRecordのOBJ_IDをDistributionGroupのOBJ_IDで結合します。私はSELECTの例でそれを明確にしておくべきですが、ArbitraryObjIDはいくつかのMessageRecord OBJ_IDでした。 ENTITY_IDは、この結合を実行することによって検索することを望んでいる、明確ではあるが未知の値です。 –

+0

あなたのOBJ_IDはユニークではないようです。マニュアルでは、同じArbitraryObjID値を3回リストして選択するので、これは同じオブジェクトです。一意でない場合は、getEntityIdに@Idとマークします。 – James

+0

ああ! OBJ_IDは一意ではなく、ENTITY_IDは索引付けされません。私は私を捨てていたのは、テーブルのために定義されたプライマリ・キーも一意性の保証もないということでした。私は、テーブルが一意であることを必要とすることなくテーブルを定義することができたことを以前にも認識していませんでしたが、ここもそこにもありません。ここにあるのはそのトリックをしたことです。ありがとう! –

関連する問題