在我的測驗中,我有一個記憶體 H2 DB,我想測驗洗掉一個物體。
我的物體:
@Entity
@Table(name = "REPORT_BLOB")
public class BlobInfoDBVO {
@Id
@Column(name = "REPORT_ID")
private long reportId;
}
測驗代碼
@Test
void deleteByReportId() {
var reportId = 1L;
EntityTransaction tx = em.getTransaction();
tx.begin();
var blobInfo = new BlobInfoDBVO();
blobInfo.setReportId(reportId);
em.persist(blobInfo);
tx.commit();
tx.begin();
BlobInfoDBVO findByReportId1 = em.find(BlobInfoDBVO.class, reportId);
assertNotNull(findByReportId1); // ---- OK
var getByReportId1 = blobInfoDao.getByReportId(reportId);
assertTrue(getByReportId1.isPresent()); // ---- OK
tx.commit();
tx.begin();
blobInfoDao.deleteByReportId(reportId);
tx.commit();
tx.begin();
var getByReportId2 = blobInfoDao.getByReportId(reportId);
assertFalse(getByReportId2.isPresent()); // ---- OK
BlobInfoDBVO findByReportId2 = em.find(BlobInfoDBVO.class, reportId);
assertNull(findByReportId2); // ---- FAILS
tx.commit();
}
這是我的 DAO 代碼,用于查找和洗掉物體reportId:
public class BlobInfoDaoImpl {
EntityManager em;
public BlobInfoDaoImpl(EntityManager em) {
super();
this.em = em;
}
public Optional<BlobInfoDBVO> getByReportId(long reportId) {
var query =
em.createQuery(
"""
select blobInfo
from BlobInfoDBVO blobInfo
where blobInfo.reportId = :reportId
""",
BlobInfoDBVO.class);
query.setParameter("reportId", reportId);
return query
.getResultStream()
.findFirst();
}
public void deleteByReportId(long reportId) {
var query =
em.createQuery(
"""
delete from BlobInfoDBVO
where reportId = :reportId
""");
query.setParameter("reportId", reportId);
query.executeUpdate();
}
}
洗掉物體后,我無法通過呼叫我的 DAO ( getByReportId) 手動執行查詢來找到它,這是正確和預期的。
但是,當我使用使用欄位作為主鍵的find方法時(它被標記為) - 它仍然回傳未洗掉的物體,即使之前提交了事務。EntityManagerreportId@Id
任何想法?
hobernate 核心 5.6.14
quarkus-test-h2 2.14.0.Final
uj5u.com熱心網友回復:
JPAEntityManager可能正在快取查詢的結果,甚至跨事務(不確定規范是否說應該或不應該發生)。嘗試在EntityManager.clear()洗掉提交后清除其快取,以便后續查詢轉到真實資料庫。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/531987.html
標籤:爪哇休眠h2
