使用JPA获取最后插入记录的主键

时间:2012-10-04 02:01:19

标签: postgresql jpa java-ee-6

我一直在使用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);
        }
// ...

1 个答案:

答案 0 :(得分:2)

JPA规范要求在持久化之后,如果正在使用ID生成策略,则使用有效ID填充实体。你不必做任何事情。