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.
감사합니다
예외를 던지면 그렇다고합니다. 개인적으로 나는 이런 종류의 API를 견딜 수 없습니다. 모든 경우에 모든 것이 허위 예외 처리를 강요합니다. try-catch 블록으로 코드를 사용하면됩니다.getSingleResult()
또는 목록을 쿼리하여 비어 있는지 확인할 수 있습니다. 예외는 아닙니다. (외래 키 또는 제약 조건 중 하나 또는 둘 다 또는 조합으로 불가능한 경우에도) 기술적으로 기본 키 조회를하지 않기 때문에 여러 결과가있을 수 있습니다. 이것은 아마도 더 해결책 일 것입니다.
다음 도우미 메서드에서 논리를 캡슐화했습니다.
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();
}
}
이 작업을 수행하기위한 좋은 옵션이 있습니다.
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);
}
Java 8에서 시도하십시오.
Optional first = query.getResultList().stream().findFirst();
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);
try / catch 사용하여 하여이 문제를 처리하려는 경우 if / else처럼 작동하는 데 사용할 수 있습니다. 기존의 레코드를 사용하여 새 레코드를 추가했습니다.
try { //if part
record = query.getSingleResult();
//use the record from the fetched result.
}
catch(NoResultException e){ //else part
//create a new record.
record = new Record();
//.........
entityManager.persist(record);
}
다음은 Rodrigo IronMan의 구현을 기반으로 한 유형 / 일반 버전입니다.
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);
}
내가 추천 할 대안이 있습니다.
Query query = em.createQuery("your query");
List<Element> elementList = query.getResultList();
return CollectionUtils.isEmpty(elementList ) ? null : elementList.get(0);
이것은 Null Pointer Exception에 대한 보호를 제공하며 1 개의 결과 만 반환됩니다.
그러니 하지마!
두 가지 옵션이 있습니다.
선택을 실행하여 개수가 0이 아닌 경우에만 데이터를 가져옵니다. 또는
다른 종류의 쿼리 (결과 집합을 가져옴)를 사용하고 결과가 0 개 이상인지 확인합니다. 1이 꺼내면 완료됩니다.
나는 Cletus와 동의하여 두 제안을 제안 할 것입니다. (잠재적으로) 2 개의 쿼리보다 더 나은 성능을 제공합니다. 또한 작업량이 적습니다.
uniqueResultOptionalorg.hibernate.query.Query 의 문서화되지 않은 메소드 가 트릭을 수행해야합니다. 대신 잡을 필요의 NoResultException당신은 단지 호출 할 수 있습니다 query.uniqueResultOptional().orElse(null).
기존의 유용한 유용한 비트 (결과 수 제한, 결과가 고유한지 확인)를 결합하고 안정화 된 방법 이름 (Hibernate)을 사용할 수 있습니다.
/**
* Return a single instance that matches the query, or null if the query returns no results.
*
* @param query query (required)
* @param <T> result record type
* @return record or null
*/
public static <T> T uniqueResult(@NotNull TypedQuery<T> query) {
List<T> results = query.setMaxResults(2).getResultList();
if (results.size() > 1) throw new NonUniqueResultException();
return results.isEmpty() ? null : results.get(0);
}
나는 0 List<?> myList = query.getResultList();과 myList.size()같은지 사용 하고 확인 하여 해결했습니다 .
다음은 Google Guava 및 TypedQuery를 사용하여 다른 사람들이 제안한 것과 동일한 논리입니다 (resultList 가져 오기, 유일한 요소 또는 null 반환).
public static <T> getSingleResultOrNull(final TypedQuery<T> query) {
return Iterables.getOnlyElement(query.getResultList(), null);
}
Guava는 결과 집합에 둘 이상의 결과가있는 경우 제공되지 않은 IllegalArgumentException을 반환합니다. (이 예외는 getOnlyElement ()의 클라이언트 보유한 의미가 있는데, 이는 결과 목록을 인수로 취하지 만 getSingleResultOrNull ()의 클라이언트에게는 이해하기 어렵 기 때문입니다.)
이번에는 Scala에서 또 다른 확장이 있습니다.
customerQuery.getSingleOrNone match {
case Some(c) => // ...
case None => // ...
}
이 포주와 함께 :
import javax.persistence.{NonUniqueResultException, TypedQuery}
import scala.collection.JavaConversions._
object Implicits {
class RichTypedQuery[T](q: TypedQuery[T]) {
def getSingleOrNone : Option[T] = {
val results = q.setMaxResults(2).getResultList
if (results.isEmpty)
None
else if (results.size == 1)
Some(results.head)
else
throw new NonUniqueResultException()
}
}
implicit def query2RichQuery[T](q: TypedQuery[T]) = new RichTypedQuery[T](q)
}
따라서이 페이지의 모든 "예외없이 다시 쓰기 시도"솔루션에는 사소한 문제가 있습니다. NonUnique 예외가 발생하지 않는 경우 잘못된 경우에도 발생합니다 (아래 참조).
적절한 해결책은 (아마도)
public static <L> L getSingleResultOrNull(TypedQuery<L> query) {
List<L> results = query.getResultList();
L foundEntity = null;
if(!results.isEmpty()) {
foundEntity = results.get(0);
}
if(results.size() > 1) {
for(L result : results) {
if(result != foundEntity) {
throw new NonUniqueResultException();
}
}
}
return foundEntity;
}
목록에 0 개의 것이 있다면 null로 반환되고, 목록에 다른 요소가 있으면 고유하지 않은 값을 반환하지만 선택 항목 중 하나가 제대로 설계되지 않은 경우 고유하지 않은 값을 반환하지 않습니다. .
의견을 바랍니다.
이 코드를 사용 :
return query.getResultList().stream().findFirst().orElse(null);
때 findFirst()호출 어쩌면 NullPointerException이 발생했습니다.
가장 좋은 방법은 다음과 가능합니다.
return query.getResultList().stream().filter(Objects::nonNull).findFirst().orElse(null);
결과 목록을 얻은 다음 비어 있는지 확인하여 달성했습니다.
public boolean exist(String value) {
List<Object> options = getEntityManager().createNamedQuery("AppUsers.findByEmail").setParameter('email', value).getResultList();
return !options.isEmpty();
}
너무 짜증나서 getSingleResult()예외가 발생합니다.
던졌다 :
- NoResultException- 결과가없는 경우
- NonUniqueResultException- 문서에서 더 많은 정보를 얻을 수있는 둘 이상의 결과 및 기타 예외 인 경우
JPA 2.2 에서 .getResultList()목록이 비어 있는지 확인하거나 스트림을 만드는 대신 스트림을 반환하고 첫 번째 요소를 사용할 수 있습니다.
.getResultStream()
.findFirst()
.orElse(null);
저에게 효과가 있습니다.
Optional<Object> opt = Optional.ofNullable(nativeQuery.getSingleResult());
return opt.isPresent() ? opt.get() : null;
참고 URL : https://stackoverflow.com/questions/2002993/jpa-getsingleresult-or-null
'IT' 카테고리의 다른 글
| .XSD 파일에서 Java 클래스 생성…? (0) | 2020.07.11 |
|---|---|
| Windows의 설치 시간과 날짜는 어떻게 찾습니까? (0) | 2020.07.11 |
| 범위에서 임의의 이중 생성 (0) | 2020.07.11 |
| UnicodeDecodeError : 'utf8'코덱이 위치 0에서 바이트 0xa5를 사용할 수 없습니다 : 유효하지 않은 시작 바이트 (0) | 2020.07.10 |
| .resx 파일의 모든 리소스를 반복 (0) | 2020.07.10 |