2 Replies Latest reply on Jun 1, 2006 10:16 AM by pbrewer_uk

    Validation without @IfInvalid

    pbrewer_uk

      I understand that the @IfInvalid annotation is no longer the best way to perform validation and that the <s:validate> and <s:validateAll> tags can be used to validate data-entry entity fields on the front-end.

      How would I go about validating the entire entity bean (not just the data-entry fields) on form submission?

      For example: A user enters two numbers - they're multiplied together and saved in the db. The entered numbers are validated by @Max(5) but the calculated result has a validation of @Max(10). Consequently, entering a value of 4 and 4 stores a result of 16 and yields an exception in the log, but an apparent success on the front-end.

      Is there a nice way to validate (or even just catch the exception) and then warn the user?

      (As a side note: is the @Valid tag now obsolete too?)

      Thanks in advance, Peter.

      Exception in log

      01-06 11:04:56 ERROR [PhaseListenerManager] Exception in PhaseListener INVOKE_APPLICATION(5) afterPhase
      java.lang.IllegalStateException: Could not commit transaction
       at org.jboss.seam.jsf.SeamExtendedManagedPersistencePhaseListener.commitOrRollback(SeamExtendedManagedPersistencePhaseListener.java:98)
       at org.jboss.seam.jsf.SeamExtendedManagedPersistencePhaseListener.afterPhase(SeamExtendedManagedPersistencePhaseListener.java:52)
       at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter(PhaseListenerManager.java:89)
       at org.apache.myfaces.lifecycle.LifecycleImpl.invokeApplication(LifecycleImpl.java:345)
       at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:86)
       at javax.faces.webapp.FacesServlet.service(FacesServlet.java:137)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:23)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:45)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:868)
       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:663)
       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
       at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
       at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
       at java.lang.Thread.run(Thread.java:595)
      Caused by: org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=null:1149156241562/8, BranchQual=null:1149156241562, localId=0:8], status=STATUS_NO_TRANSACTION; - nested throwable: (org.hibernate.validator.InvalidStateException: validation failed for: uk.co.iblocks.data.NumberTest)
       at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:1286)
       at org.jboss.tm.TxManager.commit(TxManager.java:588)
       at org.jboss.ejb3.embedded.UserTransactionImpl.commit(UserTransactionImpl.java:90)
       at org.jboss.seam.jsf.SeamExtendedManagedPersistencePhaseListener.commitOrRollback(SeamExtendedManagedPersistencePhaseListener.java:87)
       ... 28 more
      Caused by: org.hibernate.validator.InvalidStateException: validation failed for: uk.co.iblocks.data.NumberTest
       at org.hibernate.validator.event.ValidateEventListener.validate(ValidateEventListener.java:104)
       at org.hibernate.validator.event.ValidateEventListener.onPreInsert(ValidateEventListener.java:127)
       at org.hibernate.action.EntityInsertAction.preInsert(EntityInsertAction.java:139)
       at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:44)
       at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
       at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
       at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
       at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
       at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
       at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:988)
       at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:337)
       at org.hibernate.transaction.CacheSynchronization.beforeCompletion(CacheSynchronization.java:59)
       at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:3074)
       at org.jboss.tm.TransactionImpl.beforePrepare(TransactionImpl.java:2632)
       at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:1194)
      

      numberTest.xhtml
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:t="http://myfaces.apache.org/tomahawk"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:s="http://jboss.com/products/seam/taglib">
       <head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
       </head>
      
       <body>
       <f:view>
       <h:form>
       <s:validateAll>
       First: <h:inputText id="no1" value="#{numberTest.first}" /><br />
       Second: <h:inputText id="no2" value="#{numberTest.second}" /><br/>
       <h:commandButton id="calculate" action="#{numbersAction.save}" value="save" /><br />
       <h:messages showDetail="true" />
       </s:validateAll>
       </h:form>
       </f:view>
       </body>
      </html>
      


      Session bean - NumbersAction.java
      @Stateful
      @Name ( "numbersAction" )
      @Scope ( ScopeType.CONVERSATION )
      public class NumbersAction implements Numbers {
      
       private static final Logger LOG = Logger.getLogger( NumbersAction.class );
      
       @PersistenceContext(type=EXTENDED)
       private EntityManager em;
      
       @Valid
       @Out(scope = ScopeType.CONVERSATION)
       @In(required=false)
       private NumberTest numberTest ;
      
       @Begin
       @Factory ( "numberTest" )
       public void initNumberTest () {
       numberTest = new NumberTest();
       }
      
      
       @End ( ifOutcome = "saved" )
       public String save() {
       try {
       numberTest.setResult(numberTest.getFirst() * numberTest.getSecond()) ;
       em.persist( numberTest );
       FacesMessages.instance().add("Data saved fine.") ;
       return "saved";
       } catch (Exception ex) {
       FacesMessages.instance().add("Cannot save data.") ;
       return null ;
       }
       }
      
       @Remove
       @Destroy
       public void destroy() { }
      
      
      }
      


      EntityBean - NumbersTest.java
      @Entity
      @Table(name="NUMBER_TEST")
      @SequenceGenerator(name="numberTest", sequenceName="NUMBER_TEST_SEQ")
      public class NumberTest implements Serializable {
      
       private static final Logger LOG = Logger.getLogger(NumberTest.class) ;
      
       private Integer id ;
       private Integer first;
       private Integer second;
       private Integer result;
      
       public NumberTest() { }
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO, generator="numberTest")
       @Column(name="NUMBER_ID")
       @NotNull
       public Integer getId() {
       return this.id ;
       }
       protected void setId(Integer id) {
       this.id = id ;
       }
      
       @Column(name="FIRST")
       @Max(value=5, message="First value must be less than 5.")
       public Integer getFirst () {
       return first;
       }
       public void setFirst ( Integer first ) {
       this.first = first;
       }
      
      
       @Column(name="SECOND")
       @Max(value=5, message="Second value must be less than 5.")
       public Integer getSecond () {
       return second;
       }
       public void setSecond ( Integer second ) {
       this.second = second;
       }
      
       @Column(name="RESULT")
       @Max(value=10, message="Result value must be less than 10.")
       public Integer getResult () {
       return result;
       }
       public void setResult ( Integer result ) {
       this.result = result;
       }
      
      }
      


        • 1. Re: Validation without @IfInvalid
          gavin.king

          Try Component.forName(""numbersAction").getValidator()

          • 2. Re: Validation without @IfInvalid
            pbrewer_uk

            The Component.forName(""numbersAction").getValidator() doesn't seem to behave correctly as far as I can tell, but thanks for the suggestion. See code snippet and stack trace below.

            So I've now added a utility method to my library that validates an entity (I've included this at the end of the post for anyone else to use).

             @End ( ifOutcome = "saved" )
             public String save() {
             try {
             numberTest.setResult(numberTest.getFirst() * numberTest.getSecond()) ;
            
             ClassValidator cv = Component.forName("numbersAction").getValidator() ;
             // line 88 follows
             InvalidValue[] invalidValues = cv.getInvalidValues(numberTest) ;
            
             for (InvalidValue iv : invalidValues) {
             FacesMessages.instance().add(iv) ;
             }
             if (invalidValues.length == 0) {
             em.persist(numberTest) ;
             FacesMessages.instance().add("Data saved fine.") ;
             return "saved" ;
             } else {
             return null ;
             }
            
             } catch (Exception ex) {
             LOG.error("Error saving.", ex) ;
             FacesMessages.instance().add("Cannot save data.") ;
             return null ;
             }
             }
            
            


            But bizarrely gives the error below, despite this definitely being the correct class type:

            java.lang.IllegalArgumentException: not an instance of: class uk.co.iblocks.data.NumberTest
             at org.hibernate.validator.ClassValidator.getInvalidValues(ClassValidator.java:287)
             at org.hibernate.validator.ClassValidator.getInvalidValues(ClassValidator.java:270)
             at uk.co.iblocks.web.NumbersAction.save(NumbersAction.java:88)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
             at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
             at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
             at org.jboss.seam.interceptors.ValidationInterceptor.validateTargetComponent(ValidationInterceptor.java:64)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
             at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
             at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
             at org.jboss.seam.interceptors.OutcomeInterceptor.interceptOutcome(OutcomeInterceptor.java:21)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
             at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
             at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
             at org.jboss.seam.interceptors.RollbackInterceptor.rollbackIfNecessary(RollbackInterceptor.java:30)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
             at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
             at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
             at org.jboss.seam.interceptors.BijectionInterceptor.bijectTargetComponent(BijectionInterceptor.java:33)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
             at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
             at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
             at org.jboss.seam.interceptors.ConversationInterceptor.endOrBeginLongRunningConversation(ConversationInterceptor.java:68)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
             at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
             at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
             at org.jboss.seam.interceptors.BusinessProcessInterceptor.manageBusinessProcessContext(BusinessProcessInterceptor.java:60)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
             at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
             at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
             at org.jboss.seam.interceptors.RemoveInterceptor.removeIfNecessary(RemoveInterceptor.java:39)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
             at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:87)
             at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
             at org.jboss.seam.ejb.SeamInterceptor.aroundInvokeInContexts(SeamInterceptor.java:73)
             at org.jboss.seam.ejb.SeamInterceptor.aroundInvoke(SeamInterceptor.java:45)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
             at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.entity.ExtendedPersistenceContextPropagationInterceptor.invoke(ExtendedPersistenceContextPropagationInterceptor.java:71)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
             at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:201)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:81)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:78)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContainer.java:199)
             at org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.java:98)
             at $Proxy88.save(Unknown Source)
             at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
             at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
             at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
             at java.lang.reflect.Method.invoke(Method.java:585)
             at com.sun.el.parser.AstValue.invoke(AstValue.java:151)
             at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:283)
             at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
             at com.sun.facelets.el.LegacyMethodBinding.invoke(LegacyMethodBinding.java:69)
             at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:63)
             at javax.faces.component.UICommand.broadcast(UICommand.java:106)
             at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:94)
             at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:168)
             at org.apache.myfaces.lifecycle.LifecycleImpl.invokeApplication(LifecycleImpl.java:343)
             at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:86)
             at javax.faces.webapp.FacesServlet.service(FacesServlet.java:137)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
             at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
             at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:23)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
             at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:45)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
             at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
             at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
             at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
             at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
             at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
             at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
             at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:868)
             at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:663)
             at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
             at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
             at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
             at java.lang.Thread.run(Thread.java:595)
            


            Utility method to validate entities
             public static <T> boolean isValid(T entity) {
            
             // get the validator
             Class<T> entityClass = (Class<T>)entity.getClass() ;
             ClassValidator<T> entityValidator = new ClassValidator<T>( entityClass );
             InvalidValue[] invalidValues = entityValidator.getInvalidValues(entity) ;
             for (InvalidValue iv : invalidValues) {
             FacesMessages.instance().add(iv) ;
             }
             return invalidValues.length == 0 ;
            
             }