2014-04-09 2 views
0

빈 검증과 함께 JSF를 사용하려고합니다. 기본적으로, 모든 유효성 검사가 예상대로, 내가 올바른 메시지가 작동 잘 작동하지만, 내 글래스 피시 콘솔에서 예외가있다 : 나는 정의의 제약뿐만 아니라 미리 정의 된 제약 조건을 사용하는 경우JSF와 Bean 유효성 검사 : ConstraintViolationException

Warnung: EJB5184:A system exception occurred during an invocation on EJB MyEntityFacade, method: public void com.mycompany.testbv.AbstractFacade.create(java.lang.Object) 
Warnung: javax.ejb.EJBException 
at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.java:748) 
.... 
.... 
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544) 
at java.lang.Thread.run(Thread.java:744) 
Caused by: javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details. 

이 예외가 발생는.

여기 내 샘플 코드입니다.

샘플 엔티티 :

@Entity 
@ValidEntity 
public class MyEntity implements Serializable { 

    private static final long serialVersionUID = 3104398374500914142L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    @Size(min = 2) 
    private String name; 

    public MyEntity(String name) { 
     this.name = name; 
    } 

    public MyEntity() { 

    } 

    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 

사용자 정의 제한 :

@Constraint(validatedBy = MyValidator.class) 
@Target({FIELD, METHOD, TYPE}) 
@Retention(RUNTIME) 
public @interface ValidEntity { 
    String message() default "fail"; 
    Class<?>[] groups() default {}; 
    Class<? extends Payload>[] payload() default {}; 
} 

사용자 정의 유효성 검사기 :

public class MyValidator implements ConstraintValidator<ValidEntity, MyEntity>{ 

    @Override 
    public void initialize(ValidEntity a) { 
    } 

    @Override 
    public boolean isValid(MyEntity t, ConstraintValidatorContext cvc) { 
     return false; 
    } 
} 

샘플 컨트롤러 :

@Named 
@SessionScoped 
public class MyController implements Serializable { 

    private static final long serialVersionUID = -6739023629679382999L; 

    @Inject 
    MyEntityFacade myEntityFacade; 
    String text; 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    } 

    public void saveNewEntity() { 
     try { 
      myEntityFacade.create(new MyEntity(text)); 
     } catch (Exception e) { 
      Throwable t = e; 
      while (t != null) { 
       if (t instanceof ConstraintViolationException) { 
        FacesContext context = FacesContext.getCurrentInstance(); 
        Set<ConstraintViolation<?>> constraintViolations = ((ConstraintViolationException) t).getConstraintViolations(); 
        for (ConstraintViolation<?> constraintViolation : constraintViolations) { 
         FacesMessage facesMessage = new FacesMessage(constraintViolation.getMessage()); 
         facesMessage.setSeverity(FacesMessage.SEVERITY_ERROR); 
         context.addMessage(null, facesMessage); 
        } 
       } 
       t = t.getCause(); 
      } 
     } 
    } 
} 
01 23,516,

샘플 JSF 페이지 :

<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://xmlns.jcp.org/jsf/html"> 
    <h:head></h:head> 
    <h:body> 
     <h:form> 
      <h:messages id="messages" /> 
      <h:inputText value="#{myController.text}" /> 
      <h:commandButton value="Save" action="#{myController.saveNewEntity()}" /> 
     </h:form> 
    </h:body> 
</html> 

MyEntityFacade 통화 만은 엔티티 관리자에서 유지됩니다.

앞서 언급했듯이 응용 프로그램은 정상적으로 실행되고 있으며 올바른 메시지는 shwon이지만 Glassfish 콘솔에서는이 예외가 발생하지 않도록하고 싶습니다.

here과 같이 persistence.xml의 유효성 검사 모드를 NONE으로 설정하는 것은 유효하지 않으므로 선택 사항이 아닙니다.

버전 2.2에서 JSF를 사용합니다. 구현은 Mojarra입니다. Bean 검증 버전은 1.1이며, 구현은 Hibernate Validator이다. Application Server는 Glassfish 4.0입니다.

답변

1

JSF에서는 클래스 수준 제약 조건이 작동하지 않습니다. this answer을보십시오. '저장'버튼을 누르면 JSF는 이름에 2 문자 이상이 있는지 확인하고 ValidEntity 제약 조건을 고려하지 않습니다. 한편, JPA는 bean이 유효하지 않고 예외를 throw한다고 불평합니다. facelet 당신이 MyController.text 속성을가하면서

UPDATE

1) @Size 제약 MyEntity.name 재산입니다. JSF 관점에서 확인할 사항은 없습니다. MyEntity에 대한 지식이 전혀 없습니다.

2) ValidEntity는 항상 유효하지 않으므로 MyEntity.name을 Facelet에 올바르게 설정하더라도 JPA는 항상 유효성 검사를 비활성화하지 않는 한 예외를 throw합니다.

+0

답장을 보내 주셔서 감사합니다. 예외는 JPA에 의해 던져 집니까? 그러나 왜 그것을 정확하게 붙잡을 수 없는가? 그리고 내 질문에 언급했듯이 @Size 구속 조건 만 위반하면 예외가 throw됩니다. – mare

+0

업데이트를 참조하십시오. 귀하의 컨트롤러에서 MyEntity에 대한 참조가 없음을 알 수 없었습니다. – Alf

+0

아, facelet의 텍스트 속성을 완벽하게 사용할 수 있습니다.예, 그것은 단지 테스트 코드이며, 커스텀 Validator는 항상 실패해야하고 예외가 throw되어야합니다. 그러나 제 문제는 제 질문입니다. MyController 클래스에서이 예외가 완전하게 잡히지 않는 이유는 무엇입니까? "실패"메시지가 JSF 메시지 구성 요소에 인쇄되기 때문에 GF 콘솔에서 stacktrace (내 초기 질문 참조)가 인쇄됩니다. 이것은 나를 위해 조금 혼란 스럽다. – mare