Search code examples
javaspringjspspring-mvcspring-form

How to print in a <form:input> the value of Set that is a field of the main object of the form


I have an object called Menu. It has a field called voceMenuList that is a Set

@Component
@Entity
@Table(name="menu")
@Configurable
public class Menu implements Serializable{      
    ....        
    @OneToMany(mappedBy="menu", fetch=FetchType.EAGER)
    private Set<VoceMenu> voceMenuList; 

    public Set<VoceMenu> getVoceMenuList() {
        return voceMenuList;
    }

    public void setVoceMenuList(Set<VoceMenu> voceMenuList) {
        this.voceMenuList = voceMenuList;
    }
    .....   
}

Im trying to build a form to save or update a Menu. I did something link this:

<form:form action="editMenu" method="post" commandName="menu">        
    ......  
    <c:forEach items="${menu.voceMenuList}" varStatus="counter">            
        <form:input path="voceMenuList[${counter.index}].id" maxlength="11"/>
     .....

But, when I try to save the object Menu, I get this error:

Invalid property 'voceMenuList[0]' of bean class [com.springgestioneerrori.model.Menu]: Cannot
get element with index 0 from Set of size 0, 
accessed using property path 'voceMenuList[0]'

The way I handle the forEach is not correct


Solution

  • The path is relative to your commandName, and you're getting an issue 'cause the framework is trying to find a property voceMenu inside your Menu bean, you should use a JSTL's status object, something like

    <c:forEach items="${menu.voceMenuList}" var="voceMenu" varStatus="count">
    

    and than

    <form:input path="voceMenuList[${count.index}].id" maxlength="11"/>
    

    in order to bind the values properly

    UPDATE on your comment

    The further issue you're facing is related to dynamically adding to a Set, this post explains it well, and list the possible solutions Spring 3 MVC: one-to-many within a dynamic form (add/remove on create/update)

    You can always choose to use a form-backing bean, and populate your entity afterwards. It would help you alleviate this issue, and would decouple your view from the entity, e.g. make it more robust against property name changes