2010-04-10 10 views
9

Ho creato una namedquery con ejb per verificare se il nome utente è utilizzato. Quando il singleResult è nullo, allora ottengo la seguente eccezione:javax.persistence.NoResultException: getSingleResult() non ha richiamato nessuna entità

javax.persistence.NoResultException: getSingleResult() did not retrieve any entities 

Ma questa eccezione è il risultato che voglio, quando il nome utente è libero.

Ecco il codice:

public User getUserByUsername(String username) throws DAOException{ 
    try{ 
     Query q = em.createNamedQuery(User.getUserByUsername); 
     q.setParameter("username", username); 
     return (User) q.getSingleResult(); 
    }catch(Exception e){ 
     throwException(username, e); 
     return null; 
    } 
} 

Qualcuno sa qual è il problema. :(

vorrei tornare nulla e don `t ottenere un'eccezione.

La ringrazio molto

+0

mostra la query denominata? – Bozho

risposta

27

È sembrano rigenerare l'eccezione nel blocco catch con l'istruzione throwException(username, e);. Se vi aspettate per ottenere l'utente o null senza alcuna eccezione dovrebbe essere simile al seguente:?

public User getUserByUsernameOrNull(String username) { 
    try{ 
     Query q = em.createNamedQuery(User.getUserByUsername); 
     q.setParameter("username", username); 
     return (User) q.getSingleResult(); 
    } catch(NoResultException e) { 
     return null; 
    } 
} 
+1

perfetto. Grazie mille. –

0

Che cosa il metodo throwException do

È stata generata un'eccezione al suo interno ma si sta utilizzando il messaggio dell'eccezione precedente?

8

Utilizzare invecee verificare se lo List è vuoto (con elemento zero). Altrimenti, la lista contiene un elemento e tu semplicemente lo restituisci.

+0

Questa dovrebbe essere la risposta preferita, poiché evita il blocco di gestione delle eccezioni, che in questo caso sembra essere stato appannato dal client. http://blog.takipi.com/ignore-checked-exceptions-all-the-cool-devs-are-doing-it-based-on-600000-java-projects/ – michaelok

+0

La classe Iterables di Guava, in particolare il metodo getFirst, mostra come l'eccezione per un caso non eccezionale può essere evitata: getFirst 'Restituisce il primo elemento in iterable o defaultValue se l'iterable è vuoto. – michaelok

2

Si verifica il comportamento definito quando si chiama getSingleResult e non è stata trovata nessuna voce: Viene emesso un numero NoResultException. Puoi prendere NoResultException nella clausola catch, perché la transazione non sarà contrassegnata come rollback, quando JPA lancia NoResultException. Oppure puoi usare getResultList() e controllare se la dimensione è esattamente "1", quindi sai di aver trovato il tuo utente.

Inoltre, non restituire "[null]" se l'utente non è stato trovato, ma lanciare una UserNotFoundException controllata (da definire). Ma questo dipende dal contratto del metodo che implementerai.

+0

Puoi approfondire: "perché è runtimeexception" catch exception "non si adatta" .. Perché no? –

2

Michael ha detto: "È possibile rilevare NoResultException nella clausola catch, perché la transazione non verrà contrassegnata come rollback, quando JPA lancia NoResultException.". Sembra che per alcune implementazioni jpa, la NoResultException eseguirà la transazione rollbak, che viola le specifiche jpa, in base a questo articolo: NoResultException marks transaction rollback

+1

Hai ragione, questo succede in Glassfish 4.0 – Roland

0

Se l'applicazione utilizza Primavera Roo la risposta più votata non funziona: l'eccezione è catturato da aspetti e non avete mai ottenere il desiderato NoResultException. L'unico modo per risolvere il problema è utilizzare e verificare zero, uno o più risultati nella risultante List, come indicato nella seconda risposta più votata.

Problemi correlati