Почему объект найден по идентификатору в JPA, а не по запросу JPQL? - PullRequest
1 голос
/ 05 августа 2010

У меня есть тестовый пример JUnit 4 с аннотацией Spring @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;
}

Ответы [ 3 ]

3 голосов
/ 06 августа 2010

Объект находится в текущем сеансе (диспетчер объектов) - он находится в постоянном состоянии и ожидает сброса.Метод get сначала проверяет содержимое сеанса и, если не найден, обращается к базовой базе данных.В вашем случае объект был только что сохранен в том же сеансе, поэтому он найден и возвращен.

Обновление: выяснилось, что проблема в неправильном менеджере транзакций, следовательно, объект не был сброшенв базу данных.См. Объяснение Паскаля.

3 голосов
/ 06 августа 2010

Если вы используете режим сброса по умолчанию (AUTO) и выполняете запрос в транзакции, спецификация JPA гарантирует, что запрос не вернет устаревшие или неверные данные:

3.6.2 Запросы и FlushMode

Настройка режима очистки влияет на Результат запроса выглядит следующим образом.

Когда запросы выполняются в пределах транзакция, если FlushModeType.AUTO устанавливается на объект Query, или если настройка режима промывки для постоянства контекст AUTO (по умолчанию) и настройки режима промывки не было указанный для объекта Query, поставщик постоянства несет ответственность для обеспечения того, чтобы все обновления состояние всех субъектов в постоянный контекст, который может потенциально влияет на результат запрос виден для обработки запрос. Постоянный провайдер реализация может достичь этого путем сбрасывая эти сущности в базы данных или с помощью других средств. Если FlushModeType.COMMIT установлено, эффект обновлений, сделанных для объектов в постоянный контекст при запросах не указано.

public enum FlushModeType {
    COMMIT,
    AUTO
}

Если транзакция не активна, поставщик постоянства не должен сбрасывать база данных.

Предполагая, что вы используете AUTO, проверьте транзакционную сторону.

0 голосов
/ 05 августа 2010

в первом случае идентификатор - это целое число

, во втором - идентификатор: строка

целое число никогда не будет равным строке

...