Spring MVC with JPA databinding

hibernate, java, jpa, spring

Solution

Spring automatically binds simple object types like String and Number, but for complex objects like `java.util.Date` or your own defined types, you will need to use what is called a `PropertyEditors` or `Converters`, both could solve your problem.

Spring already has a predefiend `PropertyEditors` and `Converters` like @NumberFormat and @DateTimeFormat

You can use them directly on your fields like this

public class Child {

  @DateTimeFormat(pattern="dd/MM/yyyy")
  private Date birthday;

  @DateTimeFormat(iso=ISO.DATE)
  private Date graduationDay;

  @NumberFormat(style = Style.CURRENCY)
  private Integer myNumber1;

  @NumberFormat(pattern = "###,###")
  private Double myNumber2;

}

Spring also allows you to define your own type converters which you must use it combined with Spring `ConversionService`

For example if you have a `Color` class like this

public class Color {
  private String colorString;

  public Color(String color){
     this.colorString = color;
  }
}

You would define the color converter for example like this

public class StringToColor implements Converter<String, Color> {
  public Color convert(String source) {
    if(source.equal("red") {
       return new Color("red");
    }

    if(source.equal("green") {
       return new Color("green");
    }

    if(source.equal("blue") {
       return new Color("blue");
    }

    // etc

    return null;
  }
}

To check more about converters check this, also check this to know the difference between `Converters` and `PropertyEditors`

Problem

My problem is with having Spring bind the data I get from a form to a JPA entity. The wierd part is, it works just fine if I do not look at the BindingResults. The BindingResults says there were binding errors when an empty string is passed in for the field graduation, but I know it does bind them correctly because when I don't check Hibernate updates the database perfectly. Is there a way to not have to write logic to circumnavigate the wrongly fired binding errors? ``` @Entity @Table(name="child") public class Child { @Id @Column(name="id") private Integer childId; @ManyToOne(fetch=FetchType.EAGER ) @JoinColumn(name="house", referencedColumnName="house") private House house; @NotNull() @Past() @Column(name="birthday") private Date birthday; @Column(name="graduation_date") private Date graduationDay; } ``` I have tried the following lines in a property editor to no avail ``` SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy"); registry.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); ``` Here is the method signature for the controller method Handling the request ``` @Controller @SessionAttributes(value="child") @RequestMapping(value="child") public class ChildModController { @RequestMapping(value="save-child.do", params="update", method = RequestMethod.POST) public @ResponseBody Map<String,?> updateChild( HttpServletRequest request, @Valid @ModelAttribute(value="child")Child child, BindingResult results) } ``` This is what I get from the BindingResult class as a message ``` 09:01:36.006 [http-thread-pool-28081(5)] INFO simple - Found fieldError: graduationDay, Failed to convert property value of type java.lang.String to required type java.util.Date for property graduationDay; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type @javax.persistence.Column java.util.Date for value '; nested exception is java.lang.IllegalArgumentException ```

Original source

Related problems