2012-10-04 69 views
0

我一直在使用JPA插入实体到数据库中,但我遇到了一个问题,我需要做一个插入并获取最后插入的记录的主键。获取最后插入的记录的主键与JPA

使用PostgreSQL我会使用INSERT RETURNING语句来返回记录ID,但是使用实体管理器完成所有这些操作,我知道的唯一方法就是使用SELECT CURRVAL。

所以问题就出现了,我有几个数据源通过OpenMQ将数据发送到消息驱动bean(通常是每个源一次10-100条消息),并且在此MDB中,我通过实体管理器将其持久保存到PostgreSQL。它在这一点我认为会有一个“竞争条件喜欢”有这么多插入的效果,我不一定会使用SELECT 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); 
     } 
// ... 
+0

在插入新记录之前使用SELECT nextval()*。 –

+0

我刚刚发现实体在flush()之后实际上是populats pk和seq val,并且它似乎正在工作。 尝试{em.persist(r); em.flush(); r.getId(); – Ender

+0

@DondiMichaelStroma呃,没有。 'nextval()'推进序列。如果你这样做,你会得到一个不会被分配到任何记录的ID。 –

回答

2

JPA规范要求坚持后,该实体具有有效ID进行填充,如果正在使用的ID生成策略。你不必做任何事情。

相关问题