How do I map several options to a ModelAttribute Set?

223 views Asked by At

I'm trying build a simple CRUD for User managing. So I have two basic beans:

public class User  {
    private static final long serialVersionUID = 1L;

    private Long userId;

    private String login;
    private String password;

    private Set<Profile> profiles;

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId= userId;
    }


    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String pass) {
        this.password = pass;
    }

    public Set<Profile> getProfiles() {
        return profiles;
    }

    public void setPerfiles(Set<Profile> perfiles) {
        this.profiles= profiles;
    }
}

And

public class Profile{
    private static final long serialVersionUID = 1L;

    private Long profileId;
    private String name;

    public Profile() {
    }

    public Profile(String name) {
        this.name= name;
    }

    public Long getProfileId() {
        return this.profileId;
    }

    public void setProfileId(Long profileId) {
        this.profileId= profileId;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name= name;
    }
}

To create a new User I created a form with a User acting as modelAttribute:

<f:form id="formCreateUser" action="${urlBase}users/saveUser"
method="post" modelAttribute="user">
<fieldset>
    <div class="edit-form">
        <f:label path="login">Login</f:label> 
        <f:input path="login" id="login" class="text ui-widget-content ui-corner-all" />
    </div>
    <div class="edit-form-multiple-select">
        <label>Available profiles</label>
        <select id="availableProfiles" multiple="multiple" class="ui-widget-content ui-corner-all" >
            <c:forEach var="profile" items="${availableProfiles}" >
                <option value="${profile.profileId}" ><s:message code="profile.${profile.name}"/></option>
            </c:forEach>
        </select>
    </div>
    <div class="edit-form-multiple-select-arrows" >
        <a id="moveRight" href="#" class="form-button" style="display: inline-block; margin: 5px 0px; ">&gt;&gt;</a>
        <br>
        <a id="moveLeft" href="#" class="form-button">&lt;&lt;</a>
    </div>
    <div class="edit-form-multiple-select">
        <label>Actual profiles</label>
        <f:select id="profiles" path="profiles" multiple="true" cssClass="ui-widget-content ui-corner-all">
           <c:forEach var="profile" items="${user.profiles}" >
                <f:option value="${profile.profileId}" ><s:message code="profile.${profile.name}"/></f:option>
            </c:forEach>
        </f:select>             
    </div>
</fieldset>

This form has two multiple selects:

  • One to show the available profiles that can be added to the user (these profiles are obtained from the database)
  • Another to show the actual profiles already binded to the user (as this is a new user the profile set of the User object is empty)

When I want to add some profiles to one User I move options from the availableProfiles select to the profiles select.

The thing is that if I submit the form after moving one or several profiles from one select to another I'm not able to map those profiles on the Controller. This is the Controller method:

@RequestMapping("/saveUser")
public String saveUser(@ModelAttribute User user, BindingResult bindingResult,  Model model, HttpServletRequest request){
    try{
        System.out.println(user.getProfiles()); // Here profiles are null


        return "editUser";
    }
    catch(Exception e){
        return "listUser";
    }
}

PD: I tried to bind the profileId to the Set using Formatter, CustomCollectionEditor and PropertyEditor without successing.

0

There are 0 answers