JPAを使用してエンティティをデータベースに挿入してきましたが、挿入を実行して最後に挿入されたレコードの主キーを取得する必要があるという問題が発生しました。
PostgreSQLを使用すると、レコードIDを返すINSERT RETURNINGステートメントを使用しますが、エンティティマネージャーがこれをすべて実行する場合、私が知っている唯一の方法はSELECTCURRVALを使用することです。
したがって、問題は、OpenMQを介してメッセージ駆動型Bean(通常は各ソースから一度に10〜100メッセージ)にデータを送信する複数のデータソースがあり、このMDB内でエンティティマネージャーを介してPostgreSQLにこれを永続化することです。この時点で、挿入が多すぎるという「競合状態のような」効果があり、SELECTCURRVALを使用して最後のレコードIDを取得できるとは限らないと思います。
私のMDBは、以下のようなエンティティマネージャーを介して3つのエンティティBeanを永続化します。
これをより良く行う方法についての助けは大歓迎です。
public void onMessage(Message msg) {
Integer agPK = 0;
Integer scanPK = 0;
Integer lookPK = 0;
Iterator iter = null;
List<Ag> agKeys = null;
List<Scan> scanKeys = null;
try {
iag = (IAgBean) (new InitialContext()).lookup(
"java:comp/env/ejb/AgBean");
TextMessage tmsg = (TextMessage) msg;
// insert this into table only if doesn't exists
Ag ag = new Ag(msg.getStringProperty("name"));
agKeys = (List) (iag.getPKs(ag));
iter = agKeys.iterator();
if (iter.hasNext()) {
agPK = ((Ag) iter.next()).getId();
}
else {
// no PK found so not in dbase, insert new
iag.addAg(ag);
agKeys = (List) (iag.getPKs(ag));
iter = agKeys.iterator();
if (iter.hasNext()) {
agPK = ((Ag) iter.next()).getId();
}
}
// insert this into table always
iscan = (IScanBean) (new InitialContext()).lookup(
"java:comp/env/ejb/ScanBean");
Scan scan = new Scan();
scan.setName(msg.getStringProperty("name"));
scan.setCode(msg.getIntProperty("code"));
iscan.addScan(scan);
scanKeys = (List) iscan.getPKs(scan);
iter = scanKeys.iterator();
if (iter.hasNext()) {
scanPK = ((Scan) iter.next()).getId();
}
// insert into this table the two primary keys above
ilook = (ILookBean) (new InitialContext()).lookup(
"java:comp/env/ejb/LookBean");
Look look = new Look();
if (agPK.intValue() != 0 && scanPK.intValue() != 0) {
look.setAgId(agPK);
look.setScanId(scanPK);
ilook.addLook(look);
}
// ...