Pergunta

Eu tenho um caso de teste Junit 4 com a primavera @Transactional Anotação que salva um objeto e, em seguida, tenta encontrá -lo. O caso de teste passa quando eu uso esta implementação:

@Override
public EventSummary findEventSummaryById(Integer id) {
    return em.find(EventSummary.class, id);
}

Ele falha quando eu uso essa implementação (e depois altere qual método eu chamo no caso de teste):

@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;
}
Foi útil?

Solução

Se você estiver usando o modo de descarga padrão (AUTO) e se você estiver executando sua consulta em uma transação, a especificação JPA garante que uma consulta não retorne dados obsoletos ou incorretos:

3.6.2 Consultas e FlushMode

A configuração do modo de descarga afeta o resultado de uma consulta da seguinte maneira.

Quando as consultas são executadas dentro de uma transação, se FlushModeType.AUTOestá definido no Query objeto, ou se a configuração do modo de descarga para o contexto de persistência for AUTO (o padrão) e uma configuração de modo de descarga não foi especificada para o Query Objeto, o provedor de persistência é responsável por garantir que todas as atualizações do estado de todas as entidades no contexto de persistência que possam afetar o resultado da consulta sejam visíveis para o processamento da consulta. A implementação do provedor de persistência pode conseguir isso liberando essas entidades para o banco de dados ou por outros meios. Se FlushModeType.COMMIT está definido, o efeito das atualizações feitas às entidades no contexto de persistência nas consultas não é especificado.

public enum FlushModeType {
    COMMIT,
    AUTO
}

Se não houver transação ativa, o provedor de persistência não deve liberar para o banco de dados.

Supondo que você esteja usando AUTO, verifique o lado transacional.

Outras dicas

A entidade está na sessão atual (gerente de entidade) - está em estado persistente, esperando para ser liberado. O método GET primeiro verifica o conteúdo da sessão e, se não for encontrado, gira no banco de dados subjacente. No seu caso, a entidade acabou de ser salva na mesma sessão, por isso é encontrada e devolvida.

ATUALIZAÇÃO: Acontece que o problema está usando um gerenciador de transações incorreto; portanto, a entidade não foi liberada no banco de dados. Veja a explicação de Pascal.

No primeiro caso, o ID é um número inteiro

No segundo, o id é uma string

Um número inteiro nunca será igual a uma corda

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top