title: Why do I get IllegalArgumentException Cannot convert value of type String to required type Product, in Spring?
body: <p><strong>I receive the exception</strong>  </p>
  
  <blockquote>
    <p>Failed to convert property value of
    type [java.lang.String] to required
    type [beans.Product] for property
    product; nested exception is
    java.lang.IllegalArgumentException:
    Cannot convert value of type
    [java.lang.String] to required type
    [beans.Product] for property product:
    no matching editors or conversion
    strategy found</p>
  </blockquote>
  
  <p><strong>in the Errors errors object even before my DetailProductValidator starts validating through the validate method.</strong>  </p>
  
  <p>I don't understand why Spring does that. I don't have any input field that is mapped directly to the product property/object. I just use the product object's properties in the jsp. For example, I use:</p>
  
  <pre><code>&lt;form:options items="${dpBackObj.product.colorMap}"/&gt;
  &lt;!-- or --&gt;
  ${dpBackObj.product.priceInDollars}
  </code></pre>
  
  <p>but I never use:</p>
  
  <pre><code>&lt;form:input path="product"/&gt;
  </code></pre>
  
  <p><strong>Can anyone please explain why this happens? And maybe inform me of a simple solution?</strong></p>
  
  <p>The bean configuration for the controller is:</p>
  
  <pre><code>    &lt;!-- DETAIL PRODUCT FORM CONTROLLER --&gt;
  &lt;bean id="productDetailFormController" name="/detail.htm /addToCart.htm" 
          class="detailProduct.DetailProductFormController"&gt;
      &lt;property name="sessionForm" value="true" /&gt;
      &lt;property name="commandName" value="dpBackObj" /&gt;
      &lt;property name="commandClass" value="detailProduct.DetailProductBackingObject" /&gt;
      &lt;property name="validator"&gt;
          &lt;bean class="detailProduct.DetailProductValidator" /&gt;
      &lt;/property&gt;
      &lt;property name="formView" value="detail" /&gt;
      &lt;property name="successView" value="redirect:/viewCart.htm" /&gt;
      &lt;property name="cartService" ref="cartServiceImpl"/&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>The backing object for the DetailProductFormController is:</p>
  
  <pre><code>public class DetailProductBackingObject {
      private String quantityOverflowError;
      private Product product;
      private int quantity;
      private ShoppingCart shoppingCart;
      private long sizeId;
      private long colorId;
      public DetailProductBackingObject() {
          this.product = new Product();
          this.sizeId = -1;
          this.colorId = -1;
      }
      //getters and setters
  }
  </code></pre>
  
  <p>If you need some other info, I will provide. I am using Spring 2.5.5.</p>
  
  <p>Kind Regards,<br>
  Despot</p>
  
  <p><strong>EDIT1</strong> (<em>due to request from axtavt</em>):</p>
  
  <pre><code>&lt;form:form method="post" commandName="dpBackObj"&gt;
  &lt;table width="730" border="0" cellspacing="0" cellpadding="0"&gt;
      &lt;c:if test="${!empty dpBackObj.quantityOverflowError}"&gt;
          &lt;tr&gt;
              &lt;td&gt;
                  &lt;c:out value="${dpBackObj.quantityOverflowError}"/&gt;
              &lt;/td&gt;
          &lt;/tr&gt;
      &lt;/c:if&gt;
      &lt;spring:bind path="dpBackObj.*"&gt;
          &lt;c:if test="${not empty status.errorMessages}"&gt;
              &lt;div class="val-summary text-error" id="errorDivId"&gt;
                  &lt;div style="" class="val-summary text-error" id="errorDivId"&gt;
                      &lt;fmt:message key="detail.error.header"/&gt;
                      &lt;ul&gt;
                          &lt;c:forEach items="${status.errorMessages}" var="error"&gt;
                              &lt;li&gt;&lt;c:out value="${error}"/&gt;&lt;/li&gt;
                          &lt;/c:forEach&gt;
                      &lt;/ul&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          &lt;/c:if&gt;
      &lt;/spring:bind&gt;
      &lt;tr&gt;
          &lt;td width="310" align="left" valign="top"&gt;
              &lt;img src="${imagesPath}/${dpBackObj.product.largeImageUrl}" alt="${dpBackObj.product.description}" /&gt;
          &lt;/td&gt;
          &lt;td width="420" align="left" valign="top"&gt;
              &lt;div id="tls_detPName"&gt;
                  &lt;c:out value="${dpBackObj.product.name}"&gt;&lt;/c:out&gt;
              &lt;/div&gt;
              &lt;div &gt;  
                  &lt;strong class="numeric"&gt;${dpBackObj.product.priceInDollars}&lt;/strong&gt;
              &lt;/div&gt;
              &lt;div id="tls_detPDescLong"&gt;
                  ${dpBackObj.product.largeDescription}
                  &lt;br /&gt;
              &lt;/div&gt;
              &lt;div &gt;
                  &lt;table cellpadding="2" border="0"&gt;
                      &lt;tr&gt;
                          &lt;td align="right"&gt;
                              &lt;label for="p_sizes" class="label"&gt;&lt;fmt:message key="viewCart.Size"/&gt;&lt;/label&gt;
                          &lt;/td&gt;
                          &lt;td&gt;
                              &lt;form:select path="sizeId" &gt; 
                                  &lt;form:option  value="-1" label="x"/&gt; 
                                  &lt;form:options items="${dpBackObj.product.sizeMap}"/&gt;
                              &lt;/form:select&gt;
                          &lt;/td&gt;
                      &lt;/tr&gt;
                      &lt;tr&gt;
                          &lt;td align="right"&gt;
                              &lt;label for="p_colors" class="label"&gt;&lt;fmt:message key="viewCart.Color"/&gt;&lt;/label&gt;
                          &lt;/td&gt;
                          &lt;td&gt;
                              &lt;form:select path="colorId" &gt; 
                                  &lt;form:option value="-1" label="y"/&gt; 
                                  &lt;form:options items="${dpBackObj.product.colorMap}"/&gt;
                              &lt;/form:select&gt;
                          &lt;/td&gt;
                      &lt;/tr&gt;
                  &lt;/table&gt;
              &lt;/div&gt;
              &lt;div id="tls_addToCart"&gt;
                  &lt;div &gt;
                      &lt;label for="quantityId" class="label"&gt;&lt;fmt:message key="viewCart.Quantity"/&gt;:&lt;/label&gt;
                      &lt;form:input path="quantity" onkeypress="return checkForNumber(this, event)" maxlength="10" size="3" id="quantityId" cssClass="textbox-center"/&gt;
                      &lt;input type="image" name="addToCartButtonName" src="${imagesPath}/addToCartBtn.jpg" /&gt; 
                  &lt;/div&gt;
              &lt;/div&gt;
          &lt;/td&gt;
      &lt;/tr&gt;
  &lt;/table&gt;
  &lt;/form:form&gt;
  </code></pre>
  
  <p><strong>EDIT2</strong> (<em>due to JacobM's request</em>):
  This is my Validator:</p>
  
  <pre><code>public class DetailProductValidator implements Validator {
      public boolean supports(Class clazz) {
          return DetailProductBackingObject.class.equals(clazz);
      }
  
      public void validate(Object obj, Errors errors) {
          DetailProductBackingObject detailProductBackingObject = (DetailProductBackingObject) obj;
          if (detailProductBackingObject.getSizeId() == -1) {
              errors.rejectValue("sizeId", "error.detail.jsp.choose.size", null, "Input size.");
          }
      }
  }
  </code></pre>
  
  <p>When I reach the line <em>DetailProductBackingObject detailProductBackingObject =</em> I already have the error.<br>
  The converting of the request parameters to the backing object properties happens in <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/BaseCommandController.html" rel="noreferrer">http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/BaseCommandController.html</a> . This is what Spring says about the conversion:</p>
  
  <blockquote>
    <p>Populating using request parameters
    and PropertyEditors: Upon receiving a
    request, any BaseCommandController
    will attempt to fill the command
    object using the request parameters.
    This is done using the typical and
    well-known JavaBeans property
    notation. When a request parameter
    named 'firstName' exists, the
    framework will attempt to call
    setFirstName([value]) passing the
    value of the parameter. Nested
    properties are of course supported.
    For instance a parameter named
    'address.city' will result in a
    getAddress().setCity([value]) call on
    the command class.</p>
    
    <p>It's important to realise that you are
    not limited to String arguments in
    your JavaBeans. Using the
    PropertyEditor-notion as supplied by
    the java.beans package, you will be
    able to transform Strings to Objects
    and the other way around. For instance
    setLocale(Locale loc) is perfectly
    possible for a request parameter named
    locale having a value of en, as long
    as you register the appropriate
    PropertyEditor in the Controller (see
    initBinder() for more information on
    that matter.</p>
    
    <p>Validators: After the controller has
    successfully populated the command
    object with parameters from the
    request, it will use any configured
    validators to validate the object.
    Validation results will be put in a
    Errors object which can be used in a
    View to render any input problems.</p>
  </blockquote>