【发布时间】:2010-08-06 07:27:41
【问题描述】:
我尝试在一个 DAO 方法中执行多个查询。测试失败(数据未更新)。无异常记录。
public List<Domain> getNewDomains(final int maxAllowedItems, final Date timestamp) {
return getJpaTemplate().execute(new JpaCallback<List<Domain>>() {
@SuppressWarnings("unchecked")
public List<Domain> doInJpa(EntityManager entityManager) throws PersistenceException {
Calendar dayBefore = Calendar.getInstance();
dayBefore.setTime(timestamp);
dayBefore.add(Calendar.HOUR, -24);
List ids = entityManager.createQuery("SELECT d.id FROM domain d WHERE d.crawlDate IS NULL and (d.lastRead IS NULL OR d.lastRead <= :dayBefore ) ")
.setParameter("dayBefore", dayBefore.getTime())
.setMaxResults(maxAllowedItems)
.getResultList();
LOG.debug("new domain IDS : " + ids.toString());
if(ids.isEmpty()) {
return new ArrayList<Domain>();
}
int result = entityManager.createQuery("UPDATE domain d SET d.lastRead = :timestamp WHERE d.id IN (:ids)")
.setParameter("timestamp", timestamp)
.setParameter("ids", ids).executeUpdate();
LOG.debug("update result : " + result);
return entityManager.createQuery("SELECT d FROM domain d WHERE d.id IN (:ids) ")
.setParameter("ids", ids)
.setMaxResults(maxAllowedItems)
.getResultList();
}
});
}
首先选择正确处理。但更新“lastRead”字段状态相同。
测试:
@Test
public void testGetNewItems() {
List<Domain> items = domainDAO.getNewDomains(2, new Date());
Assert.assertNotNull(items);
Assert.assertTrue(items.isEmpty());
String domainName = "example.com";
Domain domain1 = new Domain(domainName);
domainDAO.save(domain1);
String domainName2 = "example2.com";
Domain domain2 = new Domain(domainName2);
domainDAO.save(domain2);
Domain domain2FromDB = domainDAO.getByName(domainName2);
Assert.assertEquals(domain2, domain2FromDB);
Assert.assertNull(domain2FromDB.getCrawlDate());
domain2FromDB.setCrawlDate(new Date());
domainDAO.update(domain2FromDB);
String domainName3 = "example3.com";
Domain domain3 = new Domain(domainName3);
domainDAO.save(domain3);
items = domainDAO.getNewDomains(2, new Date());
Assert.assertNotNull(items);
Assert.assertEquals(2, items.size());
Assert.assertTrue(items.contains(domain1));
Assert.assertTrue(items.contains(domain3));
Assert.assertFalse(items.contains(domain2FromDB));
for (Domain item : items) {
Assert.assertNotNull(item.getLastRead()); // FAILED assert
}
}
更新后需要刷机吗? 处理多个查询的正确方法是什么?
【问题讨论】: