JPA를 사용하여 데이터베이스에 엔터티를 삽입했지만 삽입을 수행하고 마지막으로 삽입 된 레코드의 기본 키를 가져와야하는 문제에 부딪혔습니다 .JPA에서 마지막으로 삽입 한 레코드의 기본 키 가져 오기
PostgreSQL을 사용하면 레코드 ID를 반환하는 INSERT RETURNING 문을 사용하지만 엔티티 관리자가이 모든 작업을 수행하면 SELECT CURRVAL을 사용하는 것이 유일한 방법입니다.
그래서 문제는 OpenMQ를 통해 메시지 드리븐 빈 (대개 각 소스에서 한 번에 10-100 개의 메시지)으로 데이터를 보내는 여러 데이터 소스가 있고이 MDB 내부에서 엔티티 관리자를 통해 PostgreSQL에이를 유지합니다. 이 시점에서 나는 이라고 생각한다.에는 "CURRVAL"을 사용하여 마지막 레코드 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);
}
// ...
새 레코드를 삽입하기 전에 SELECT nextval() *을 사용하십시오. –
방금 엔티티가 flush() 후에 seq val로 pk를 실제로 populats한다는 것을 알았습니다. 작동하고있는 것처럼 보입니다. 시도 { em.persist (r); em.flush(); r.getId(); – Ender
@DondiMichaelStroma Er, no. nextval()은 시퀀스를 진행시킨다. 그렇게하면 어떤 레코드에도 할당되지 않는 ID가 생깁니다. –