I have downloaded a working demo which working perfectly fine while I ran it. But when I have just made my way and I am using same page and functionality with registration page and then I submitting the form I am getting error:
[Field error in object 'user' on field 'userProfiles': rejected value [3]; codes [typeMismatch.user.userProfiles,typeMismatch.userProfiles,typeMismatch.java.util.Set,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.userProfiles,userProfiles]; arguments []; default message [userProfiles]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Set' for property 'userProfiles'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.idev.tpt.model.UserProfile] for property 'userProfiles[0]': no matching editors or conversion strategy found]]
JSP File:
<form:form id="userForm" action="newuser" modelAttribute="user"> <form:input type="hidden" path="id" id="id" /> <div class="form-group"> <form:input type="text" path="firstName" id="firstName" placeholder="First Name" class="form-control input-sm" /> </div> <div class="form-group"> <form:input type="text" path="lastName" id="lastName" placeholder="Last Name" class="form-control input-sm" /> </div> <div class="form-group"> <c:choose> <c:when test="${edit}"> <form:input type="text" path="ssoId" id="ssoId" placeholder="SSO ID" class="form-control input-sm" disabled="true" /> </c:when> <c:otherwise> <form:input type="text" path="ssoId" id="ssoId" placeholder="SSO ID" class="form-control input-sm" /> <div class="has-error"> <form:errors path="ssoId" class="help-inline" /> </div> </c:otherwise> </c:choose> </div> <div class="form-group"> <form:input type="password" path="password" id="password" placeholder="password" class="form-control input-sm" /> <div class="has-error"> <form:errors path="password" class="help-inline" /> </div> </div> <div class="form-group"> <form:input type="text" path="email" id="email" placeholder="email" class="form-control input-sm" /> <div class="has-error"> <form:errors path="email" class="help-inline" /> </div> </div> <div class="form-group"> <form:select path="userProfiles" items="${roles}" multiple="true" itemValue="id" itemLabel="type" class="form-control input-sm" /> </div> <!-- <div class="form-group"> <textarea class="form-control" id="prop_note" name="note" placeholder="Note" ></textarea> </div> --> <p class="demo-button btn-toolbar"> <span id="warningLbl" class="label label-warning" style="display: none;"></span> <button id="propAddBtn" type="submit" class="btn btn-primary pull-right">Save</button> <button id="propUpdateBtn" type="submit" class="btn btn-primary pull-right" style="display: none;">Update</button> <button id="propClearBtn" type="button" class="btn btn-primary pull-right" style="display: none;">Clear</button> </p> <br> </form:form>
controller:
@RequestMapping(value = { "/newuser" }, method = RequestMethod.GET) public String newUser(ModelMap model) { User user = new User(); model.addAttribute("user", user); model.addAttribute("edit", false); model.addAttribute("roles", userProfileService.findAll()); model.addAttribute("loggedinuser", getPrincipal()); return "registration"; } /** * This method will be called on form submission, handling POST request for * saving user in database. It also validates the user input */ @RequestMapping(value = { "/newuser" }, method = RequestMethod.POST) public String saveUser(@Valid User user, BindingResult result, ModelMap model) { if (result.hasErrors()) { return "registration"; } if(!userService.isUserSSOUnique(user.getId(), user.getSsoId())){ FieldError ssoError =new FieldError("user","ssoId",messageSource.getMessage("non.unique.ssoId", new String[]{user.getSsoId()}, Locale.getDefault())); result.addError(ssoError); return "registration"; } userService.saveUser(user); model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " registered successfully"); model.addAttribute("loggedinuser", getPrincipal()); //return "success"; return "registrationsuccess"; }
Model :
package com.websystique.springmvc.model; import java.io.Serializable; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.hibernate.validator.constraints.NotEmpty; @SuppressWarnings("serial") @Entity @Table(name="APP_USER") public class User implements Serializable{ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; @NotEmpty @Column(name="SSO_ID", unique=true, nullable=false) private String ssoId; @NotEmpty @Column(name="PASSWORD", nullable=false) private String password; @NotEmpty @Column(name="FIRST_NAME", nullable=false) private String firstName; @NotEmpty @Column(name="LAST_NAME", nullable=false) private String lastName; @NotEmpty @Column(name="EMAIL", nullable=false) private String email; @NotEmpty @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "APP_USER_USER_PROFILE", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "USER_PROFILE_ID") }) private Set<UserProfile> userProfiles = new HashSet<UserProfile>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getSsoId() { return ssoId; } public void setSsoId(String ssoId) { this.ssoId = ssoId; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Set<UserProfile> getUserProfiles() { return userProfiles; } public void setUserProfiles(Set<UserProfile> userProfiles) { this.userProfiles = userProfiles; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ((ssoId == null) ? 0 : ssoId.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof User)) return false; User other = (User) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; if (ssoId == null) { if (other.ssoId != null) return false; } else if (!ssoId.equals(other.ssoId)) return false; return true; } /* * DO-NOT-INCLUDE passwords in toString function. * It is done here just for convenience purpose. */ @Override public String toString() { return "User [id=" + id + ", ssoId=" + ssoId + ", password=" + password + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]"; } }
I am also using the same model provided in the demo. I didn't change anything in the model also not change related to jsp and controller. I don't understand why I am getting an error I am using the same way as like in a demo.
User profile
package com.websystique.springmvc.model; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @SuppressWarnings("serial") @Entity @Table(name="USER_PROFILE") public class UserProfile implements Serializable{ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; @Column(name="TYPE", length=15, unique=true, nullable=false) private String type = UserProfileType.USER.getUserProfileType(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof UserProfile)) return false; UserProfile other = (UserProfile) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; if (type == null) { if (other.type != null) return false; } else if (!type.equals(other.type)) return false; return true; } @Override public String toString() { return "UserProfile [id=" + id + ", type=" + type + "]"; } }
user profile converter
package com.websystique.springmvc.converter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; import com.websystique.springmvc.model.UserProfile; import com.websystique.springmvc.service.UserProfileService; /** * A converter class used in views to map id's to actual userProfile objects. */ @Component public class RoleToUserProfileConverter implements Converter<Object, UserProfile>{ static final Logger logger = LoggerFactory.getLogger(RoleToUserProfileConverter.class); @Autowired UserProfileService userProfileService; /** * Gets UserProfile by Id * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) */ public UserProfile convert(Object element) { Integer id = Integer.parseInt((String)element); UserProfile profile= userProfileService.findById(id); logger.info("Profile : {}",profile); return profile; } }
Updated
one more thing while I printing the form data using model getter method getUserProfiles() I am getting blank data so I think it's not binding the selected value.but any other column I am printing it will perfectly bind.
1 Answers
Answers 1
After your comment I updated my reply:
Probably the problem is in JSP code. When application invokes the saveUser()
method in your controller, a new User object is created. But because you have UserProfile
type in User object the application has to know how to create UserProfile
from String (when passed from <form:select path="userProfiles">
).
Either you add a custom converter from String to UserProfile
or create an UserDTO
class with Java standard types and use it in your Controller save operation. Code will be something similar to:
public String saveUser(@Valid UserDTO dto, ...) { User user = createUserFromDTO(dto); userService.saveUser(user); }
Also make sure, that you have the UserProfile
entity correctly defined with JPA annotations.
0 comments:
Post a Comment