Perchè è un oggetto trovato da id in APP, ma non attraverso una query JPQL?
Domanda
Ho un banco di prova JUnit 4 con il @Transactional
annotazioni primavera che salva un oggetto, e quindi i tentativi di trovarlo. Il banco di prova passa quando uso questa implementazione:
@Override
public EventSummary findEventSummaryById(Integer id) {
return em.find(EventSummary.class, id);
}
Non riesce quando uso questa implementazione (e quindi modificare il metodo ho chiamata nel caso di test):
@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;
}
Soluzione
Se si utilizza la modalità predefinita a filo (AUTO
) e se si sta eseguendo la query all'interno di una transazione, le garanzie specifiche JPA che una query non restituirà dati non aggiornati o non corretti:
3.6.2 Query e FlushMode
L'impostazione della modalità colore influisce sulla risultato di una query come segue.
Quando le query vengono eseguite all'interno di un operazione, se
FlushModeType.AUTO
è impostato sull'oggettoQuery
, o se la impostazione della modalità a filo per la persistenza contesto èAUTO
(il default) e una impostazione della modalità colore non è stato specificato per l'oggettoQuery
, la fornitore di persistenza è responsabile per garantire che tutti gli aggiornamenti alla stato di tutte le entità nel contesto di persistenza che potrebbe potenzialmente influenzare il risultato della interrogazione sono visibili al trattamento dei la query. Il provider di persistenza attuazione può realizzare questo vampate di calore tali enti al database o con altri mezzi. SeFlushModeType.COMMIT
è impostato, la effetto di aggiornamenti apportati alle entità in il contesto di persistenza su query non è specificato.public enum FlushModeType { COMMIT, AUTO }
Se non v'è alcuna transazione attiva, il provider di persistenza non deve filo il database.
Supponendo che si sta utilizzando AUTO
, controllare il lato transazionale.
Altri suggerimenti
Тhe entità è nella sessione corrente (entity manager) - è in stato persistente, in attesa di essere svuotati. Il metodo GET prima controlla il contenuto della sessione, e si trasforma, se non si trovano al database sottostante. Nel tuo caso, l'entità è appena stato salvato nella stessa sessione, quindi è trovato e restituito.
Aggiornamento: si è scoperto il problema sta utilizzando un gestore di transazioni non corretta, da cui l'entità non è stata lavata al database. Vedere la spiegazione di Pascal.
nel primo caso, l'id è un intero
nel secondo, l'id è una stringa
un intero non sarà mai uguale a una stringa