2016-07-19 1 views
1

나는 매우 호기심이 많습니다. EJB에서 런타임 예외를 어떻게 잡을 수 있습니까?

나는 EJB의 방법을 실행하려고 및 쿼리 방법은 일부 값과 BiFuctionFunction을 필요로 JAX-RS

public Service readSingle(...) { 
    try { 
     service.query(...); 
    } catch (final NoResultException nre) { 
     throw new NotFoundException(...); 
    } catch (final NonUniqueResultException nure) { 
     throw new BadRequstException(...); 
    } 
} 

와 결과를 반환하고 있습니다.

실제 호출은 다음과 같습니다. 좋아

try { 
     return serviceService.<Service>query(
       id, 
       ofNullable(matrixParameters.getFirst("onid")) 
       .map(Integer::parseInt).orElse(null), 
       ofNullable(matrixParameters.getFirst("tsid")) 
       .map(Integer::parseInt).orElse(null), 
       ofNullable(matrixParameters.getFirst("sid")) 
       .map(Integer::parseInt).orElse(null), 
       ofNullable(matrixParameters.getFirst("number")) 
       .map(Integer::parseInt).orElse(null), 
       ofNullable(matrixParameters.getFirst("programId")) 
       .orElse(null), 
       operatorId, 
       (builder, root) -> emptyList(), 
       TypedQuery::getSingleResult); 
    } catch (final NoResultException nre) { 
     throw new NotFoundException(
       "no entity idnetified by " + serviceIdSegment.getPath() 
       + " with " + matrixParameters.toString()); 
    } catch (final NonUniqueResultException nure) { 
     throw new BadRequestException("multiple entities identified"); 
    } 

나는 TypedQuery::getSingleResult를 통과하고 나는 그것을 던져되어야 할 때 NonUniqueResultException이 잡힐한다 기대한다.

하지만 Payara는 500으로 응답하며 로그에는 NonUniqueResultException이 코드에서 전혀 잡히지 않았 음이 표시됩니다.

ExceptionMappers를 사용하지 않도록 설정 한 결과가 동일합니다.

답변

0

확인. 나는 그것을 알아. 나는 이것을해야만했다.

try { 
     // execute EJB 
    } catch (final EJBTransactionRolledbackException ejbtre) { 
     Exception leaf = ejbtre; 
     try { 
      for (Exception c; 
       (c = ((EJBException) leaf).getCausedByException()) != null; 
       leaf = c); 
     } catch (final ClassCastException cce) { 
     } 
     logger.severe("causedByException: " + leaf); 
     if (leaf instanceof NoResultException) { 
      throw new NotFoundException(
        "no entity idnetified by " + serviceIdSegment.getPath() 
        + " with " + matrixParameters.toString()); 
     } else if (leaf instanceof NonUniqueResultException) { 
      throw new BadRequestException(
        "multiple entities identified by " 
        + serviceIdSegment.getPath() 
        + " with " + matrixParameters.toString()); 
     } 
     throw new InternalServerErrorException(ejbtre); 
    } 

예상보다 훨씬 까다 롭습니다. EJB의 메소드 설계는 좋지 않습니다.

이 작업을 더 간단하게 수행 할 수있는 방법이 있습니까?

0

제 자신을 정당화하는 데 사용한 유틸리티 클래스 중 하나를 소개하겠습니다.

public final class EJBExceptions { 

    private static final Logger logger 
      = getLogger(EJBExceptions.class.getName()); 

    public static Stream<Exception> causedByExceptions(EJBException ejbe) { 
     final Stream.Builder<Exception> builder = Stream.builder(); 
     while (ejbe != null) { 
      final Exception causedByException = ejbe.getCausedByException(); 
      if (causedByException != null) { 
       builder.add(causedByException); 
      } else { 
       break; 
      } 
      if (causedByException instanceof EJBException) { 
       ejbe = (EJBException) causedByException; 
      } else { 
       break; 
      } 
     } 
     return builder.build(); 
    } 

    public static Optional<Exception> lastCausedByException(
      final EJBException ejbe) { 
     return causedByExceptions(ejbe).reduce((first, second) -> second); 
    } 

    private EJBExceptions() { 
     super(); 
    } 
}