NoResultException i walidacja użytkownika

0

Przed dodaniem użytkownika do bazy chcę sprawdzić czy przypadkiem nie istnieje już użytkownik o tej nazwie, lecz jakbym tego nie zrobił dostaję NRE
metoda na pobranie użytkownika:

    public static Users findByUsername(String username)
            throws NoResultException {
        Users user = null;
        try {
            user = (Users) entityManager()
                    .createQuery("from Users u where u.username = :username")
                    .setParameter("username", username).getSingleResult();
            return user;

        } catch (NoResultException nre) {
            // Ignore this because as per your logic this is ok!
        }
        if (user == null) {
            return null;
        }
        return user;
    }

Fragmenty z walidatora JSF, na którym się krzaczy:

        if (Users.findByUsername(username) != null) {
            MessageFactory.addMessage("register_validate_username_exists",
                    FacesMessage.SEVERITY_ERROR, null);
            return;
        }

Wiem, że mógłbym pobrać listę użytkowników o danej nazwie i zamiast porównać do nulla to sprawdzić czy lista ma 0 elementów - jest inne i gustowniejsze wyjście z sytuacji?

1

a co z EntityManager.find() ?

0

Rozwiązanie:

public class JPAUtils {
	public static <T> T getSingleResultOrNull(TypedQuery<T> query) {
	    query.setMaxResults(1);
	    List<T> list = query.getResultList();
	    if (list.isEmpty()) {
	        return null;
	    }
	    return list.get(0);
	}
}
public static Users findByUsername(String username) {
		TypedQuery<Users> q = entityManager()
				.createQuery("from Users u where u.username = :username", Users.class)
				.setParameter("username", username);
		Users user = JPAUtils.getSingleResultOrNull(q);
		return user;
	}

czyli nie znalazłem innego sposobu jak przez listę.

0

Ja to robie inaczej. Na kolumne z nazwa loginu zakladam UNIQUE INDEX. Mianowicie, gdy narusze indeks unikalnosci JPA rzuca PersistanceException. Aby miec pewnosc, ze zostanie rzucony musze wykonac:

em.persist(obiekt);
em.flush(); // to powoduje, ze mam gwarancje rzucenia wyjatku

Nastepnie w stacktrace mam podane nazwe indeksu, ktory zostal naruszony, a jego tresc uzyskuje przez e.msg(). Jaka funkcja sprawdzam naruszenie? Metoda contains, a argumentem jest nazwa indeksu. Na ich podstawie rzucam wlasne wyjatki (ktore informuja o konkretnym bledzie do mojej aplikacji), ktore potem moge zlapac w JSF i wyswietlic message.

1 użytkowników online, w tym zalogowanych: 0, gości: 1