Почему объект, найден ID в JPA, но не через запрос JPQL?
Вопрос
У меня есть тестовый случай Junit 4 с пружиной @Transactional
Аннотация, которая сохраняет объект, а затем пытается его найти. Тестовый случай пропускает, когда я использую эту реализацию:
@Override
public EventSummary findEventSummaryById(Integer id) {
return em.find(EventSummary.class, id);
}
Это не удается, когда я использую эту реализацию (а затем изменить, какой метод я звоню в тестовом случае):
@Override
public EventSummary findEventSummary(Integer id) {
Query query = em.createQuery("select es from EventSummary as es where es.id = :id");
query.setParameter("id", id);
EventSummary result = (EventSummary) query.getSingleResult();
return result;
}
Решение
Если вы используете режим промывания по умолчанию (AUTO
) И если вы выполняете свой запрос в транзакции, спецификация JPA гарантирует, что запрос не будет возвращать устаревые или неверные данные:
3.6.2 Запросы и пробное течение
Настройка режима промывания влияет на результат запроса следующим образом.
Когда запросы выполняются в транзакции, если
FlushModeType.AUTO
устанавливается наQuery
объект или если настройка режима промывания для контекста постоянстваAUTO
(по умолчанию) и настройка режима Flush не была указана дляQuery
Объект, поставщик настойчивости отвечает за обеспечение того, чтобы все обновления состояния всех организаций в контексте настойчивости, которые могут потенциально повлиять на результат запроса, видны для обработки запроса. Реализация поставщика постоянства может достичь этого путем промывки этих объектов к базе данных или в некоторых других средствах. ЕслиFlushModeType.COMMIT
Установлено, влияние обновлений, сделанных сущностям в контексте настойчивости при запросах не указано.public enum FlushModeType { COMMIT, AUTO }
Если нет акции транзакции, поставщик постоянства не должен прошивать в базу данных.
Предполагая, что вы используете AUTO
, Проверьте транзакционную сторону.
Другие советы
THE Сущность находится в текущем сеансе (менеджер по суждению) - он находится в постоянном состоянии, ожидая, чтобы быть промытым. Метод Get сначала проверяет содержимое сеанса и, если не найдено, повороты в базовую базу данных. В вашем случае сущность только что была сохранена на том же сеансе, поэтому оно найдено и возвращено.
Обновление: оказалось, что проблема использует неверный менеджер транзакций, следовательно, объект не был покрасен в базу данных. См. Объяснение Паскаля.
В первом случае идентификатор является целым числом
Во-вторых, идентификатор - это строка
Целое число никогда не равно строки