[java] JPA getSingleResult () 또는 널

존재하지 않는 경우 insertOrUpdate삽입 Entity하거나 존재하는 경우 업데이트 하는 메소드 가 있습니다. 이를 사용하려면, 나는에 가지고 findByIdAndForeignKey가 반환하는 경우, null삽입하지 않을 경우 다음 업데이트를. 문제는 그것이 존재하는지 어떻게 확인합니까? 그래서 나는 노력했다 getSingleResult. 그러나 예외가 발생하면

public Profile findByUserNameAndPropertyName(String userName, String propertyName) {
    String namedQuery = Profile.class.getSimpleName() + ".findByUserNameAndPropertyName";
    Query query = entityManager.createNamedQuery(namedQuery);
    query.setParameter("name", userName);
    query.setParameter("propName", propertyName);
    Object result = query.getSingleResult();
    if (result == null) return null;
    return (Profile) result;
}

하지만 getSingleResult던졌습니다 Exception.

감사



답변

예외를 던지면 getSingleResult()찾을 수 없다는 것을 나타냅니다. 개인적으로 나는 이런 종류의 API를 견딜 수 없습니다. 실질적인 이점이 없도록 허위 예외 처리를 강요합니다. try-catch 블록으로 코드를 감싸면됩니다.

또는 목록을 쿼리하여 비어 있는지 확인할 수 있습니다. 예외는 아닙니다. 실제로 기술적으로 기본 키 조회를 수행하지 않기 때문에 여러 결과가있을 수 있습니다 (외래 키 또는 제약 조건 중 하나 또는 둘 다 또는 조합으로 실제로 불가능한 경우에도). 이것은 아마도 더 적절한 해결책 일 것입니다.


답변

다음 도우미 메서드에서 논리를 캡슐화했습니다.

public class JpaResultHelper {
    public static Object getSingleResultOrNull(Query query){
        List results = query.getResultList();
        if (results.isEmpty()) return null;
        else if (results.size() == 1) return results.get(0);
        throw new NonUniqueResultException();
    }
}


답변

Java 8에서 이것을 시도하십시오.

Optional first = query.getResultList().stream().findFirst();


답변

이 작업을 수행하기위한 좋은 옵션이 있습니다.

public static <T> T getSingleResult(TypedQuery<T> query) {
    query.setMaxResults(1);
    List<T> list = query.getResultList();
    if (list == null || list.isEmpty()) {
        return null;
    }

    return list.get(0);
}


답변

Spring 은이를위한 유틸리티 메소드 를 가지고 있습니다 :

TypedQuery<Profile> query = em.createNamedQuery(namedQuery, Profile.class);
...
return org.springframework.dao.support.DataAccessUtils.singleResult(query.getResultList());


답변

(Java 8에서) 완료했습니다.

query.getResultList().stream().findFirst().orElse(null);


답변

JPA 2.2 에서 .getResultList()list가 비어 있는지 확인하거나 스트림을 만드는 대신 스트림을 반환하고 첫 번째 요소를 사용할 수 있습니다.

.getResultStream()
.findFirst()
.orElse(null);