为什么JPA persist()不会生成自动增量主ID?

mas*_*san 7 java jpa toplink-essentials

我正在使用JPA toplink-essentialSQL Server 2008

我的目标是获取将要插入表中的数据的自动增量主键值.我知道在JDBC中,有getInsertedId()方法,它给你自动增加主id的id(但是在执行insert语句之后)

在JPA中,我发现@GenratedValue annotation可以做到这一点.

@Entity
@Table(name = "tableOne")
public class TableOne implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "tableId")
    private Integer tableId;
Run Code Online (Sandbox Code Playgroud)

现在,如果我运行下面的代码,它应该给我自动增加的id 但它返回NULL ...

 EntityManager em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager();
 EntityTransaction txn = em.getTransaction();
 txn.begin();

 TableOne parent = new TableOne();
 em.persist(parent); //here I assume that id is pre-generated for me.
 System.out.println(parent.getTableId()); //this returns NULL :(
Run Code Online (Sandbox Code Playgroud)

Jam*_*mes 11

问题是你正在使用IDENTITY id生成.IDENTITY id生成无法进行预分配,因为它们需要INSERT来生成id.TABLE和SEQUENCE id生成支持预分配,我总是建议使用这些,并且由于这个问题和性能,我从不使用IDENTITY.

您可以通过调用flush()来触发在生成IDENTITY id时生成的id.


Hei*_*deh 6

只需这样做:

public void create(T entity) {
   getEntityManager().persist(entity);
   getEntityManager().flush();
   getEntityManager().refresh(entity);
}
Run Code Online (Sandbox Code Playgroud)

刷新实体后,您将获得具有适当值的ID字段.

  • 添加`flush()`的原因是`persist()`没有明确保证生成`@GeneratedValue`,但它必须在`flush()`之前或之前生成.看到这个问题:http://stackoverflow.com/questions/9087848/when-does-the-jpa-set-a-generatedvalue-id (3认同)

JSS*_*JSS 2

我们也在使用 SQL Server 2008,但它对我来说从来没有用过,所以我总是执行单独的查询"SELECT @@IDENTY"来获取插入的 id。

我在网上发现的原因是自动ID(IDENTITY)由数据库管理,并且永远不会在实体中获取,除非您提交行或手动从数据库检索信息。