他の誰かのアプリケーションからインポートした読み取り専用テーブルの上にJPAマッピングを作成しようとしています。これらは複数の100億行のテーブルであるため、スキーマを変更することはできません。1つのテーブルであるMessageテーブルにはOBJECT_ID値があり、もう1つのテーブルであるDistributionGroupテーブルには、任意のOBJECT_IDに関連付けられたENTITY_IDの多くの行があります。関連するテーブル定義は次のとおりです。
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;
そして、これら2つをリンクする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のすべてのDGRecordを反復処理するコードを実行しているときに、奇妙なことが起こります。
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個の異なるDGRecordを返しませんが、同じDGRecord値をn回返します。ここで、nは、クエリを手動で実行して返された個別の行の数です。これが適切かどうかはわかりませんが、実際には同じオブジェクトをn回ループしています(System.out.println(dg)が同じpackage.DistributionGroup@MemoryAddressをn回返すことで証明されています)。
何が間違っているのでしょうか。どうすれば修正できますか。テーブルスキーマの変更、または結合テーブルの追加は、コストがかかるため、事実上不可能であることに注意してください。しかし、これは人間として十分に機能するため、現在の設定ではまだ機能するはずです。