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

时间:2011-11-17 15:22:36

标签: java jpa playframework

See this question

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

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

4 个答案:

答案 0 :(得分:9)

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

此外,只要认为有必要,JPA提供者就可以进行刷新操作。但是,为了方便起见,JPA提供程序将数据库操作延迟到事务将被提交的时间。

某些自动ID生成器策略必须访问数据库以获取PK值(据我记得IDENTITY策略的工作方式)。
相反,TABLESEQUENCE生成器不一定需要命中DB来获取ID值。他们使用allocationSize参数向DB TABLE或SEQUENCE询问将在没有与数据库进一步通信的情况下提供给新实体的批次 ID。

答案 1 :(得分:3)

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

来自JPABase._save()源代码:

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

EntityManagerHelper.getEntityManager().flush();

如果你不打电话,对象将丢失,无法保存到DB。

所以在调用它之后,你会在对象中识别它。