See this question。在JPA/Play中提交事務之前,實體如何獲取ID?
事實證明,即使沒有手動提交事務,在提交TX之前,該人在調用save()方法後仍有一個ID。
不是數據庫負責分配ID字段嗎?如果是這樣,在提交之前如何填寫ID字段?在提交TX之前是否與DB進行任何通信?
See this question。在JPA/Play中提交事務之前,實體如何獲取ID?
事實證明,即使沒有手動提交事務,在提交TX之前,該人在調用save()方法後仍有一個ID。
不是數據庫負責分配ID字段嗎?如果是這樣,在提交之前如何填寫ID字段?在提交TX之前是否與DB進行任何通信?
是的,允許JPA在事務提交之前與數據庫進行通信。它可能發生,即當你明確調用EntityManager#flush()
。
此外,JPA提供程序只要感覺有必要就可以執行刷新操作。但是,爲了方便起見,JPA提供程序將數據庫操作延遲到交易執行的時間。
一些自動ID生成器策略必須擊中數據庫才能獲得PK值(據我記得IDENTITY
戰略那樣工作)。
與此相反,TABLE
或SEQUENCE
生成器不需要命中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和承諾之間,調用保存或更新方法之後,你應該使用:
EntityManagerHelper.getEntityManager().flush();
如果你不調用它,對象將丟失,並且不能被保存到數據庫中。
所以在調用它之後,你會在對象中使用它的id。
爲什麼? JPA照顧它......如果有任何機會,當您提交交易時ID將無法使用,它將會失敗......只要您知道交易可能失敗(由於許多原因),我認爲儘早使用ID是可以的。 – ripper234