Announcement Announcement Module
Collapse
No announcement yet.
comparing dates in validator Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • comparing dates in validator

    Hi. I'm trying to compare two dates upon validation to ensure that one date is after the other, but I keep getting an error. If I don't specify any conditions in the validator for these date fields, and no dates are selected, I get an error reported back that I pick up with status.errorMessage in the bind tag (I assume because the object couldn't bind without the dates being entered). However once I add conditions into my validator object to compare them (to ensure that one date follows another), I get a nullpointerexeption:

    my init binder:

    protected void initBinder(HttpServletRequest request,
    ServletRequestDataBinder binder) {

    NumberFormat nf = NumberFormat.getNumberInstance();
    // must follow this in request for bind to work: "Aug 18, 2004 1:31:44 PM"
    DateFormat df = DateFormat.getDateTimeInstance();

    binder.registerCustomEditor(Long.class, null, new CustomNumberEditor(Long.class, nf, true));
    binder.registerCustomEditor(Date.class, null, new CustomDateEditor(df, false));
    }

    in my Validator object:

    public void validate(Object obj, Errors errors) {

    Project project = (Project)obj;

    if(project == null) {
    errors.rejectValue("name", "error.not-specified", null, "Invalid Project Entry");
    log.debug("--------------------------------project == null-----------------------------");
    }
    else {
    log.debug("--------------------Validating with " + project + ": " + project.getName() + "----------------");
    if(project.getDescription() == null || "".equals(project.getDescription())) {
    errors.rejectValue("description", "errors.required", new Object[] {new String("Description")}, "A Description is Required");
    }
    if(project.getName() == null || "".equals(project.getName())) {
    errors.rejectValue("name", "errors.required", new Object[] {new String("Name")}, "A Project Name is Required");
    }
    /*
    if(project.getCompletion_date().before(project.get Create_date())) {
    errors.rejectValue("completion_date", "errors.date-toosoon", new Object[] {new String(project.getCompletion_date().toString()), new String(project.getStart_date().toString())}, "Date too soon");
    }
    */
    }

    }


    the error upon post:

    DEBUG - ValidationUtils.invokeValidator(50) | Invoking validator [com.projectscribe.web.ProjectFormValidator@27de24]
    DEBUG - ProjectFormValidator.validate(41) | --------------------Validating with com.projectscribe.model.Project@156c69c: lkj----------------
    ERROR - FrameworkServlet.service(342) | Could not complete request
    java.lang.NullPointerException
    at com.projectscribe.web.ProjectFormValidator.validat e(ProjectFormValidator.java:49)
    at org.springframework.validation.ValidationUtils.inv okeValidator(ValidationUtils.java:56)
    at org.springframework.web.servlet.mvc.BaseCommandCon troller.bindAndValidate(BaseCommandController.java :298)
    at org.springframework.web.servlet.mvc.AbstractFormCo ntroller.handleRequestInternal(AbstractFormControl ler.java:236)
    at org.springframework.web.servlet.mvc.AbstractContro ller.handleRequest(AbstractController.java:128)
    at org.springframework.web.servlet.mvc.SimpleControll erHandlerAdapter.handle(SimpleControllerHandlerAda pter.java:44)
    at org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:522)
    at org.springframework.web.servlet.FrameworkServlet.s ervice(FrameworkServlet.java:321)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:802)

    Any thoughts/ideas? Is there a better way to approach this?

  • #2
    It looks to me that you need to check for null dates in your validator.

    Comment


    • #3
      I added this to be complete (thanks), but I still get the error on the date compare line in the validator

      if(project.getCompletion_date() == null || "".equals(project.getCompletion_date())) {
      errors.rejectValue("completion_date", "errors.required", new Object[] {new String("Completion Date")}, "A Completion Date is Required");
      }
      if(project.getStart_date() == null || "".equals(project.getStart_date())) {
      errors.rejectValue("start_date", "errors.required", new Object[] {new String("Start Date")}, "A Start Date is Required");
      }


      this is what it doesn't like:

      if(project.getCompletion_date().before(project.get Create_date())) {

      I also tried this condition, to no avail:

      if(project.getCompletion_date().compareTo(project. getStart_date()) < 0) {

      It errors out if I enter no dates, a correct sequence of dates, or an incorrect one. If I take this condition in the validator out, the date entry works just fine...it binds it, I am able to insert the record into the database, etc. in the controller.

      Comment


      • #4
        another data point

        the dates I am using are java.util.Date types.

        Hibernate seems to be able to read and insert the accurate dates just fine from within the controller (via my service object), but when I call toString() or do a compare (see above) from within my validator, or onBindAndValidate() to try to debug I get that same nullpointer exception.

        protected void onBindAndValidate(HttpServletRequest request, Object obj,
        BindException errors) throws Exception {

        Project project = (Project)obj;
        log.debug("--------------- in onbindandvalidate -------------------------------------------------------");
        log.debug("--------------- start date: " + project.getStart_date().toString() + " ----------------------");
        log.debug("--------------- completion date: " + project.getCompletion_date().toString() + " ----------------------");
        }

        another anomoly: when I add the checks in the validator for null/empty for the dates, it is erroring out as null:

        DEBUG - AbstractView.render(225) | Rendering view with name 'projectForm' with model {project=com.projectscribe.model.Project@158473e, org.springframework.validation.BindException.proje ct=org.springframework.validation.BindException: BindException: 2 errors; Field error in object 'project' on field 'completion_date': rejectedValue=[null]; codes=[errors.required.project.completion_date,errors.req uired.completion_date,errors.required.java.util.Da te,errors.required]; arguments=[(java.lang.String)[Completion Date]]; defaultMessage=[A Completion Date is Required]; Field error in object 'project' on field 'start_date': rejectedValue=[null]; codes=[errors.required.project.start_date,errors.required .start_date,errors.required.java.util.Date,errors. required]; arguments=[(java.lang.String)[Start Date]]; defaultMessage=[A Start Date is Required]} and static attributes {}

        How can I Hibernate the command object (with dates) when the date fields are in fact null when I check them with the validator?

        Comment


        • #5
          I haven't used Hibernate, so I can't really help too much there. My suggestion would be to create some tests which convert from Strings to dates for your Project object and try running it with tests and possibly a debugger (I think you can find some tips on this in the Spring docs). Also, have you tried searching the Hibernate list for date issues? Also, try removing the .toString() from the logging and see if that at least helps with dumping the values (if any).

          Comment


          • #6
            solved

            I was calling the wrong get method for the variable I was validating...doh!

            Thanks for the response.

            --Joe

            Comment


            • #7
              what worked

              here's what worked, if anyone is interested:

              initBinder:
              Code:
               protected void initBinder&#40;HttpServletRequest request,
                                            ServletRequestDataBinder binder&#41; &#123;
                      
                      NumberFormat nf = NumberFormat.getNumberInstance&#40;&#41;;
                      binder.registerCustomEditor&#40;Long.class, null, new CustomNumberEditor&#40;Long.class, nf, true&#41;&#41;;
                      
                      // must follow this in request for bind to work&#58; "Aug 18, 2004 1&#58;31&#58;44 PM"
                      //DateFormat df = DateFormat.getDateTimeInstance&#40;&#41;;
                      SimpleDateFormat df = new SimpleDateFormat&#40;"MMM dd, yyyy h&#58;mm&#58;ss a"&#41;; 
                      df.setLenient&#40;false&#41;;
                      binder.registerCustomEditor&#40;Date.class, null, new CustomDateEditor&#40;df, true&#41;&#41;;
                  &#125;
              Validator:

              Code:
              if&#40;project.getProjected_completion_date&#40;&#41; == null | "".equals&#40;project.getProjected_completion_date&#40;&#41;&#41;&#41; &#123;
              				errors.rejectValue&#40;"projected_completion_date", "errors.required", new Object&#91;&#93; &#123;new String&#40;"Projected Completion Date"&#41;&#125;, "A Completion Date is Required"&#41;;
              			&#125;
              			if&#40;project.getProjected_start_date&#40;&#41; == null | "".equals&#40;project.getProjected_start_date&#40;&#41;&#41;&#41; &#123;
              				errors.rejectValue&#40;"projected_start_date", "errors.required", new Object&#91;&#93; &#123;new String&#40;"Projected Start Date"&#41;&#125;, "A Start Date is Required"&#41;;
              			&#125;
              			
              			if&#40;project.getProjected_start_date&#40;&#41; != null && project.getProjected_completion_date&#40;&#41; != null && &#40;project.getProjected_completion_date&#40;&#41;.compareTo&#40;project.getProjected_start_date&#40;&#41;&#41; < 0&#41;&#41; &#123;
              				errors.rejectValue&#40;"projected_completion_date", "error.date-toosoon", new Object&#91;&#93; &#123;new String&#40;"Projected Completion Date"&#41;, new String&#40;"Projected Start Date"&#41;&#125;, "A Completion Date is Required"&#41;;
              			&#125;
              messages:

              Code:
              error.date-toosoon=&#123;0&#125; comes before &#123;1&#125;, please correct.
              errors.required=&#123;0&#125; is required.

              Comment

              Working...
              X