实体实例化后立即检索实体对象的ID?

时间:2015-06-18 16:58:24

标签: jsf jpa

实体实例化后,JPA中是否有办法检索Entity对象的id?例如Person person = new Person();

目前我在我的实体类中使用以下策略: @GeneratedValue(strategy = GenerationType.IDENTITY)

如果没有“Dummy Id”策略,在数据库中的表设置实际主键之前有一个dummyId,例如-10等?请注意,MySQL DB中的主键设置为AutoIncrement。

我需要这个的原因是能够在列表中添加新实体并使用JSF数据表中的id对它们进行排序,然后再将它们保存到数据库中。

2 个答案:

答案 0 :(得分:0)

在持久化之前无法检索ID - 只是因为在您持久保存实体之前它没有ID。这与您的策略无关。这与并发有关。

但您可以为您的用例添加自己的临时密钥:

@Entity
public class Person {
    private static final AtomicLong counter = new AtomicLong();

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private final transient long tempId = counter.decrementAndGet();

    public long getIdForComparison() {
        return id == null ? tempId : id;
    }

}

请记住,对于每个创建的对象,counter都会减少 - 即使对于那些由JPA提供程序实例化的对象也是如此。如果您只想计算新的(未经存在的)对象,或者担心原子计数器的时间,则应该为JPA使用不同的构造函数:

@Entity
public class Person {
    private static final AtomicLong counter = new AtomicLong();

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private transient long tempId;

    private String name;

    protected Person() {
        // Constructor for JPA - nothing to do, the id will get attached
    }

    public Person(String name) {
        // Constructor for creation of new objects
        tempId = counter.decrementAndGet();
        this.name = name;
    }

    public long getIdForComparison() {
        return id == null ? tempId : id;
    }

}

答案 1 :(得分:0)

没有办法不立即将其保留在数据库中,但毕竟这显然不是你想要的。如果一次只有一个“新”人,您可以手动设置“虚拟ID”。

person.setId(0L);

不要忘记在坚持之前清除它。

person.setId(null);
// ...
em.persist(person);