事实证明,即使没有手动提交事务,在提交TX之前,该人在调用save()方法后也有一个ID。
数据库不负责协助ID字段吗?如果是这样,在提交之前如何填写ID字段?在提交TX之前是否与DB进行了任何通信?
答案 0 :(得分:9)
是的,允许JPA在事务提交之前与DB通信。它可能会发生,即当您明确调用EntityManager#flush()
时。
此外,只要认为有必要,JPA提供者就可以进行刷新操作。但是,为了方便起见,JPA提供程序将数据库操作延迟到事务将被提交的时间。
某些自动ID生成器策略必须访问数据库以获取PK值(据我记得IDENTITY
策略的工作方式)。
相反,TABLE
或SEQUENCE
生成器不一定需要命中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。
所以在调用它之后,你会在对象中识别它。