Обновление и удаление запросов считаются массовыми обновлениями в JPA и имеют разные правила. Массовые обновления выполняются непосредственно в базе данных, контекст постоянства (EntityManager) не будет обновляться с этими изменениями. Поэтому, когда вы запрашиваете контекст постоянства, он находит совпадающую сущность - по незнанию возвращает устаревшие данные.
В спецификации JPA это выглядит так:
Следует соблюдать осторожность при выполнении операций массового обновления или удаления, поскольку они могут привести к
несоответствия между базой данных и сущностями в контексте активного постоянства. В общем, навалом
Операции обновления и удаления должны выполняться только внутри транзакции в новом постоянном
текст или до выборки или доступа к объектам, состояние которых может быть затронуто такими операциями.
У вас есть несколько вариантов решения проблемы.
Перепишите первый запрос, чтобы вернуть сущность, а не только идентификатор. и изменить сущность. Примерно так должно работать
public List<Domain> doInJpa(EntityManager entityManager) throws PersistenceException {
Calendar dayBefore = Calendar.getInstance();
dayBefore.setTime(timestamp);
dayBefore.add(Calendar.HOUR, -24);
List<Domain> domains = entityManager.createQuery("SELECT d FROM domain d WHERE d.crawlDate IS NULL and (d.lastRead IS NULL OR d.lastRead <= :dayBefore ) ")
.setParameter("dayBefore", dayBefore.getTime())
.setMaxResults(maxAllowedItems)
.getResultList();
if(domains.isEmpty()) {
return new ArrayList<Domain>();
}
for(Domain d : domains) {
d.setLastRead(timestamp);
}
return domains;
}
Теперь вам нужно выполнить один запрос, сущности будут синхронизированы с контекстом постоянства, и ваш тест должен пройти.
Если вы не можете обойти проблему с массовыми обновлениями, вызвав entityManager.refresh () для каждого домена - метод обновления обновит сущность с самым последним состоянием из базы данных.