在JPA / Play中提交事务之前,实体如何获取ID?

看到这个问题 。

事实certificate,即使没有提交事务,在提交TX之前,该人在调用save()方法之后也有一个ID。

数据库是否负责协助ID字段? 如果是这样,在提交之前如何填写ID字段? 在提交TX之前是否与DB进行任何通信?

是的,允许JPA在事务提交之前与DB通信。 它可能发生,即当您显式调用EntityManager#flush()

此外,允许JPA提供者在认为必要时进行刷新操作。 但是,由于方便,JPA提供程序会将数据库操作延迟到事务提交的时间。

一些自动ID生成器策略必须到达数据库才能获得PK值(据我所知, IDENTITY策略以这种方式工作)。
相反, TABLESEQUENCE生成器不需要命中DB来获取ID值。 他们使用allocationSize参数向DB TABLE或SEQUENCE请求一批 ID,这些ID将在不与数据库进一步通信的情况下提供给新实体。

玩! 每次使用模型上的save()方法保存对象时,都会刷新持久性上下文(将更改写入数据库并允许它获取生成的ID):

从JPABase._save()源代码:

 if (!em().contains(this)) { em().persist(this); PlayPlugin.postEvent("JPASupport.objectPersisted", this); } // ... try { em().flush(); } catch (PersistenceException e) { // ... } 

据我所知,在持久存在之前,我们无法得到对象的id(假设它是自动编号的)。 我个人认为分配一些应由RDBMS在其外部完成的东西是非常危险的。

在begintransaction和commit之间,在调用save或update方法之后,你应该使用:

 EntityManagerHelper.getEntityManager().flush(); 

如果你不调用它,对象将丢失,无法保存到DB。

因此,在调用它之后,您将在对象中获取它的id。