Announcement Announcement Module
Collapse
No announcement yet.
Failed to convert property value of type [java.lang.String] Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Failed to convert property value of type [java.lang.String]

    First off, let me say that I am new to the whole Java/Hibernate/Spring world. I am working on my first project and I've gotten stuck. Here is my problem. I have two objects, Panel and PanelType.
    Here is my hibernate mapping of Panel:
    Code:
    <class name="Panel" table="tblPanel">
    	<id name="id" column="Id" type="java.lang.Integer">
    		<generator class="native" />
    	</id>
    	<property name="startTime" column="StartTime" type="java.util.Date" not-null="true" />
    	<property name="length" column="Length" type="java.lang.Integer" not-null="true" />
    	<property name="maxUsers" column="MaxUsers" type="java.lang.Integer" not-null="true" />
    	<property name="rewardPoint" column="RewardPoints" type="java.lang.Integer" not-null="true" />
    	<property name="notified" column="Notified" type="boolean" not-null="true"/>
    	<property name="productId" column="ProductId" type="java.lang.Integer" not-null="true"/>
    	<many-to-one name="panelTypes" class="PanelType" column="PanelTypeId" />
    	<set name="panelUserLookUps" table="tblPanelUserLookUp">
    		<key column="panelId"/>
    		<many-to-many column="userlId" class="User"/>
    	</set>
    </class>
    Here is my hibernate mapping of PanelType:
    Code:
    <class name="PanelType" table="tblPanelType">
    	<id name="id" column="Id" type="java.lang.Integer">
    		<generator class="native"/>
    	</id>
    	<property name="name" column="Name" type="java.lang.String" not-null="true"/>
    	<property name="description" column="Description" type="java.lang.String" not-null="true"/>
    	<property name="background" column="Background" type="java.lang.Boolean" not-null="true"/>
    	<property name="rscId" column="RSCId" type="java.lang.Integer" not-null="true"/>
    </class>
    Here is my Panel class:
    Code:
    public class Panel extends BaseHibernateObject &#123;
    
    	private Date startTime;
    	private int length;
    	private int maxUsers;
    	private int rewardPoint;
    	private boolean notified;
    	private int productId;
    	private PanelType panelTypes;
    	private Set panelUserLookUps;
    
    	public PanelType getPanelTypes&#40;&#41; &#123;
    		return panelTypes;
    	&#125;
    	public void setPanelTypes&#40;PanelType type&#41; &#123;
    		panelTypes = type;
    	&#125;
    ...
    On my controller, I have the PanelTypes binded to the form
    Code:
    	protected Map referenceData&#40;HttpServletRequest request&#41; throws Exception &#123;
    		Map model = new HashMap&#40;&#41;;
    		try &#123;
    			model.put&#40;Constants.CURRENT_RSC, request.getSession&#40;true&#41;.getAttribute&#40;Constants.CURRENT_RSC&#41;&#41;;
    			RSC rsc = &#40;RSC&#41; request.getSession&#40;true&#41;.getAttribute&#40;Constants.CURRENT_RSC&#41;;
    			model.put&#40;"AllPanelTypes", rsc.getPanelTypes&#40;&#41;&#41;;
    		&#125; catch &#40;Exception e&#41; &#123;
    			//no rsc id
    			model.put&#40;Constants.CURRENT_RSC, null&#41;;
    			model.put&#40;"AllPanelTypes", null&#41;;
    		&#125;
    		return model;
    	&#125;
    And then I'm using this in my jsp to display the PanelTypes in a drop down:
    Code:
    <tr>
    	<td class="required">Panel Type&#58;</td>
    	<td>
    		<spring&#58;bind path="activePanel.panelTypes">
    			<select name="panelTypes">
    				<option value="0"<c&#58;if test="$&#123;status.value == null&#125;"> SELECTED</c&#58;if>>Select a panel type</option>
    				<c&#58;forEach items="$&#123;AllPanelTypes&#125;" var="pt">
    					<option value="<c&#58;out value="$&#123;pt.id&#125;" />" <c&#58;if test="$&#123;status.value == pt.id&#125;"> SELECTED</c&#58;if>><c&#58;out value="$&#123;pt.name&#125;"/></option>
    				</c&#58;forEach>
    			</select>
    		</spring&#58;bind>
    	</td>
    </tr>
    Now, for the most part, this works. However, when I submit the form, I get the following error:
    Failed to convert property value of type [java.lang.String] to required type [panelType] for property 'panelType'
    I have searched throughout Google as well as the forums here and found references to custom editors and/or binders, but I haven't the slightest idea on how to get this working. If someone could be so gracious as to help me out, I would be very grateful.

    Thanks,
    Neo

  • #2
    You're 99% of the way there. Take a look at http://springframework.org/docs/refe...-customeditors section 3.13 of the reference manual.

    In a nutshell: you need to tell Spring how to convert a String to a PanelType and you do that by making a new class that extends PropertyEditorSupport and registering that as the "glue" that will do this conversion for you.

    Take a look at the setAsText(String text) method in that example -- you'll want to swap out the ExoticType class with your PanelType one.

    As an aside, you might want to rename your field (and your getters and setters) from panelTypes (with an 's') to one without it as you're not dealing with a plural. If you have more than one you'll use the 's' format but your type will be a List. It just makes it easier when someone else picks up your code and expects to get a List of objects when they see the plural form.

    Comment


    • #3
      @cwilkes,
      Thanks for the tip, however, I'm still coming up short. This is what I've done:

      I've created my PanelTypePropertyEditor class
      Code:
      public class PanelTypePropertyEditor extends PropertyEditorSupport &#123; 
      	private String format;
      	private TastePanelManager tpManager; 
      	
      	public TastePanelManager getTastePanelManager&#40;&#41; &#123;
      		return tpManager;
      	&#125;
      	
      	public void setTastePanelManager&#40;TastePanelManager manager&#41; &#123;
      		tpManager = manager;
      	&#125;
      
      	public void setFormat&#40;String format&#41; &#123;
      		this.format = format;
      	&#125;
          
      	public void setAsText&#40;String text&#41; &#123;
      		if &#40;format != null && format.equals&#40;"upperCase"&#41;&#41; &#123;
      			text = text.toUpperCase&#40;&#41;;
      		&#125;
      		PanelType type = &#40;PanelType&#41; tpManager.getPanelTypeById&#40;Integer.parseInt&#40;text&#41;&#41;;
      		setValue&#40;type&#41;;
      	&#125;
      &#125;
      And then I added this to my controller's initBinder:
      Code:
      binder.registerCustomEditor&#40;PanelType.class,"panelTypes", new PanelTypePropertyEditor&#40;&#41;&#41;;
      I altered my jsp to this:
      Code:
      <tr>
      	<td class="required">Panel Type&#58;</td>
      	<td>
      		<spring&#58;bind path="activePanel.panelTypes"> 
      			<select size="1" name='<c&#58;out value="$&#123;status.expression&#125;" />'>
      				<option value="0"<c&#58;if test="$&#123;activePanel.panelTypes.id==null&#125;"> SELECTED</c&#58;if>>Select a panel type</option>
      				<c&#58;forEach var="pt" items="$&#123;AllPanelTypes&#125;"> 
      					<option value='<c&#58;out value="$&#123;pt.id&#125;" />'<c&#58;if test="$&#123;activePanel.panelTypes.id==pt.id&#125;"> SELECTED</c&#58;if>><c&#58;out value="$&#123;pt.name&#125;" /></option>
      				</c&#58;forEach>
      			</select>
      		</spring&#58;bind>
      	</td>
      </tr>
      Now, I get the list of panel Types w/ the first option selected (since I don't have any existing panels yet). I can fill out the form and submit it, but when I do, I get this:
      [4/23/05 13:39:20:214 EDT] 3fe63fe6 DispatcherSer E org.springframework.web.servlet.DispatcherServlet TRAS0014I: The following exception was logged java.lang.NullPointerException
      at java.lang.Throwable.<init>(Throwable.java)
      at java.lang.Throwable.<init>(Throwable.java)
      at java.lang.NullPointerException.<init>(NullPointerE xception.java:60)
      at com.yum.web.tastepanel.bus.util.PanelTypePropertyE ditor.setAsText(PanelTypePropertyEditor.java:56)
      What am I missing now? I know I'm getting close.

      Thanks,
      neo

      Comment


      • #4
        Looks like you are creating your editor like so:
        Code:
        binder.registerCustomEditor&#40;PanelType.class,"panelTypes", new PanelTypePropertyEditor&#40;&#41;&#41;;
        But in your editor you having a setting for some sort of manager:
        Code:
        public void setTastePanelManager&#40;TastePanelManager manager&#41; &#123;
              tpManager = manager;
           &#125;
        which you're not doing. I suspect that's where your NPE is coming from, where you reference the non-set "tpManager" field.

        Comment


        • #5
          @cwilkes,
          I guess I should have explained that. tpManager comes from this:
          import com.yum.web.tastepanel.bus.managers.TastePanelMana ger;
          Which handles all of my calls to the database (i.e. getPanelTypeById). I don't think that is what is causing my NPE.[/quote]

          Comment


          • #6
            Ok, upon further investigating, the class is not recognizing tpManager. When I step through the code in debug mode as soon as it hits that line, it goes to the catch part instaed of stepping into the dao class. So how do I get it to recognize that tpManager is the dao class so that it can retrieve the PanelType object to pass back?

            Comment


            • #7
              I don't think you're setting the tpManager ... change your code to be like this:

              Code:
              public TastePanelManager getTastePanelManager&#40;&#41; &#123;
                if &#40;tpManager == null&#41; throw new RuntimeException&#40;"Didn't set tpManager"&#41;;      
                return tpManager;
              &#125;
                 
              public void setAsText&#40;String text&#41; &#123;
                if &#40;format != null && format.equals&#40;"upperCase"&#41;&#41; &#123;
                  text = text.toUpperCase&#40;&#41;;
                &#125;
                PanelType type = &#40;PanelType&#41; getTastePanelManager&#40;&#41;.getPanelTypeById&#40;Integer.parseInt&#40;text&#41;&#41;;
                    setValue&#40;type&#41;;
              &#125;

              Comment


              • #8
                i think that's the problem too, b/c when i step through the code in debug mode, it never hits the getters and setters for tpManager. How do I register it so that it does?

                Comment


                • #9
                  Your problem lies with this creation of the editor:
                  Code:
                  binder.registerCustomEditor&#40;PanelType.class,"panelTypes", new PanelTypePropertyEditor&#40;&#41;&#41;;
                  You need to set the tpManager on it. You can do it like so:
                  Code:
                  PanelTypePropertyEditor ptpe = new PanelTypePropertyEditor&#40;&#41;;
                  ptpe.setTpManager&#40;tpManager&#41;;
                  binder.registerCustomEditor&#40;PanelType.class,"panelTypes", ptpe&#41;;
                  So you'll have to have a setter for the tpManager in your Controller.

                  Comment


                  • #10
                    @cwilkes,
                    You are the man!! Thanks for all of you help. This is what worked (which is pretty much what you wrote with one exception:
                    Code:
                    		PanelTypePropertyEditor ptpe = new PanelTypePropertyEditor&#40;&#41;; 
                    		ptpe.setTastePanelManager&#40;tpManager&#41;; 
                    		binder.registerCustomEditor&#40;PanelType.class, ptpe&#41;;
                    The only difference is, when I had the binder tag like this: binder.registerCustomEditor(PanelType.class, "panelTypes", ptpe);, the setter on the PanelTypePropertyEditor would not execute. But once I took that out, it worked just fine.

                    --Neo

                    Comment


                    • #11
                      Why don't you simply implement the onBind() method?

                      protected void onBind(HttpServletRequest request, Object command) throws ServletException {
                      Panel pan = (Panel) command;
                      int typeId = RequestUtils.getRequiredIntParameter(request, "typeId");
                      pan.setPanelType((PanelType) tpManager.getPanelTypeById(typeId);
                      }

                      This way you don't need to implement a new customPropertyEditor! Have you already thought how many PropertyEditors you will have to implement, all time you need to implement that type of relationship??

                      Gilberto

                      Comment

                      Working...
                      X