1 Reply Latest reply on Nov 30, 2008 4:04 AM by oman moony

    Model Validation @NotNull @NotEmpty working with UI validateAll

    oman moony Newbie
      I found this in the Seam FAQ:

      "When using <s:validate> or <s:validateAll> fields annotated with @NotNull and @Length(min=1) aren't being validated (an InvalidStateException occurs and <h:message> shows no error)

      JSF only runs validation (using Hibernate Validator if you use the s:validate/s:validateAll tags) if the input field isn't empty. To check that a field is not null / not an empty string you need to use the required="true" attribute on the JSF component tag."

      Is there any alternative to the required attribute? This violates DRY, i.e. I want my validation code in my Model, not spread out all over the UI and in the Model. And it's especially frustrating when I'm writing my integration tests and the empty validation checks don't match what the UI displays (or even acts like). In fact, the tests for empty become pretty pointless seeing as it's really done by JSF with the required attribute.

      I have tried creating my own hibernate validator called @Required that I add to the Model. But some special condition occurs for null properties on the Model - they seem to bypass the validation until the actual persist occurs, by which time a RuntimeException is thrown... what gives?!? My validator works perfectly for any condition except when the value is null... Here is the runtime that's thrown:

      |Caused by javax.faces.FacesException with message: "#{myModelHome.persist}: org.hibernate.validator.InvalidStateException: validation failed for: com.MyModel"

      org.hibernate.validator.event.ValidateEventListener.validate(ValidateEventListener.java:143)
      org.hibernate.validator.event.ValidateEventListener.onPreInsert(ValidateEventListener.java:167)
      org.hibernate.action.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:119)
      org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:42)
      org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
      org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
      org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
      org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
      org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:131)
      org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:87)
      org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
      org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:618)
      org.hibernate.impl.SessionImpl.persist(SessionImpl.java:592)
      org.hibernate.impl.SessionImpl.persist(SessionImpl.java:596)
      org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:212)
      org.jboss.seam.persistence.EntityManagerProxy.persist(EntityManagerProxy.java:137)
      org.jboss.seam.framework.EntityHome.persist(EntityHome.java:84)
      com.MyModelHome.persist(MyModelHome.java:38)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      java.lang.reflect.Method.invoke(Method.java:597)
      org.jboss.seam.util.Reflections.invoke(Reflections.java:22)|


      I have seen various post on the Internet about this problem but none have an answer. I hope I can find a more elegant solution to this other than required=true on the inputText tag.

      Thanks,
      Owen