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; ">>></a>
<br>
<a id="moveLeft" href="#" class="form-button"><<</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.