我在用户提供相同数据后访问连接表相关数据时遇到问题。
以下是相关代码
ServiceCategory.java(模型类)
@Entity
@Table(name = "servicecategory")
public class ServiceCategory extends BaseEntity {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//@Size(min = 3, max = 50)
@Column(name = "servicecatname", nullable = false)
private String serviceCatName;
//@Size(min = 3, max = 200)
@Column(name = "servicecatdescription", nullable = false)
private String serviceCatDescription;
//@Size(min = 3, max = 500)
@Column(name = "servicecatimagefilename", nullable = false)
private String serviceCatImageFileName;
@ManyToMany(targetEntity = Employee.class, cascade = { CascadeType.ALL })
@JoinTable(name = "servicecategory_employee", joinColumns = { @JoinColumn(name = "servicecatid") }, inverseJoinColumns = { @JoinColumn(name = "empid") })
private List<Employee> employees = new ArrayList<>();
@Transient
private MultipartFile serviceCatImage;
private Boolean deleted;
public String getServiceCatName() {
return serviceCatName;
}
public void setServiceCatName(String serviceCatName) {
this.serviceCatName = serviceCatName;
}
public String getServiceCatDescription() {
return serviceCatDescription;
}
public void setServiceCatDescription(String serviceCatDescription) {
this.serviceCatDescription = serviceCatDescription;
}
public String getServiceCatImageFileName() {
return serviceCatImageFileName;
}
public void setServiceCatImageFileName(String serviceCatImageFileName) {
this.serviceCatImageFileName = serviceCatImageFileName;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public MultipartFile getServiceCatImage() {
return serviceCatImage;
}
public void setServiceCatImage(MultipartFile serviceCatImage) {
this.serviceCatImage = serviceCatImage;
}
public Boolean getDeleted() {
return deleted;
}
public void setDeleted(Boolean deleted) {
this.deleted = deleted;
}
}
Employee.java(模型类)
@Entity
@Table(name = "employee")
public class Employee extends BaseEntity {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//@Size(min = 3, max = 50)
@Column(name = "empfirstname", nullable = false)
private String empFirstName;
//@Size(min = 3, max = 50)
@Column(name = "emplastname", nullable = false)
private String empLastName;
//@Size(min = 3, max = 50)
@Column(name = "empdesignation", nullable = false)
private String empDesignation;
@OneToOne
@JoinColumn(name = "employeetypeid", nullable = true)
private EmployeeType employeeType;
//@Size(min = 3, max = 500)
@Column(name = "employeeImageFileName", nullable = false)
private String employeeImageFileName;
@ManyToMany(mappedBy="employees")
private List<ServiceCategory> serviceCategories = new ArrayList<>();
private Boolean deleted;
@Transient
private MultipartFile employeeImage;
public String getEmpFirstName() {
return empFirstName;
}
public void setEmpFirstName(String empFirstName) {
this.empFirstName = empFirstName;
}
public String getEmpLastName() {
return empLastName;
}
public void setEmpLastName(String empLastName) {
this.empLastName = empLastName;
}
public String getEmpDesignation() {
return empDesignation;
}
public void setEmpDesignation(String empDesignation) {
this.empDesignation = empDesignation;
}
public String getEmployeeImageFileName() {
return employeeImageFileName;
}
public void setEmployeeImageFileName(String employeeImageFileName) {
this.employeeImageFileName = employeeImageFileName;
}
public EmployeeType getEmployeeType() {
return employeeType;
}
public void setEmployeeType(EmployeeType employeeType) {
this.employeeType = employeeType;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<ServiceCategory> getServiceCategories() {
return serviceCategories;
}
public void setServiceCategories(List<ServiceCategory> serviceCategories) {
this.serviceCategories = serviceCategories;
}
public Boolean getDeleted() {
return deleted;
}
public void setDeleted(Boolean deleted) {
this.deleted = deleted;
}
public MultipartFile getEmployeeImage() {
return employeeImage;
}
public void setEmployeeImage(MultipartFile employeeImage) {
this.employeeImage = employeeImage;
}
}
employeeadd.jsp
<section class="inner-banner">
<div class="container">
<ol class="breadcrumb">
<li><a href="#">Home</a></li>
<li><a href="#">Employees</a></li>
<li class="active">${ACTION} Employee</li>
</ol>
</div>
</section>
<!-- form section-->
<section class="formSection">
<div class="container">
<h1 class="sectionHeading">${ACTION} Employee</h1>
<div class="divider"></div>
<form:form modelAttribute="employee" enctype="multipart/form-data" method="post">
<div class="row">
<div class="form-group col-lg-6 col-md-6 col-sm-12">
<form:label path="empFirstName">Employee First Name<em class="mandatory">*</em></form:label>
<div class="col-lg-10 col-md-12 col-sm-12">
<form:input path="empFirstName" cssClass="form-control" />
<form:errors class="alert alert-danger" path="empFirstName" />
</div>
<div class="clearfix"></div>
</div>
<div class="form-group col-lg-6 col-md-6 col-sm-12">
<form:label path="empLastName">Employee Last Name<em class="mandatory">*</em></form:label>
<div class="col-lg-10 col-md-12 col-sm-12">
<form:input path="empLastName" cssClass="form-control" />
<form:errors class="alert alert-danger" path="empLastName" />
</div>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div class="form-group col-lg-6 col-md-6 col-sm-12">
<form:label path="empDesignation">Employee Designation<em class="mandatory">*</em></form:label>
<div class="col-lg-10 col-md-12 col-sm-12">
<form:input path="empDesignation" cssClass="form-control" />
<form:errors class="alert alert-danger" path="empDesignation" />
</div>
<div class="clearfix"></div>
</div>
<div class="form-group col-lg-6 col-md-6 col-sm-12">
<form:label path="employeeType">Employee Type<em class="mandatory">*</em></form:label>
<div class="col-lg-10 col-md-12 col-sm-12">
<form:select path="employeeType.id" class="selectpicker" multiple="false">
<form:option value="0" label=" -- Please Select --" />
<form:options items="${employeeTypeList}" itemValue="id" itemLabel="employeeType"/>
</form:select>
<form:errors class="alert alert-danger" path="employeeType" />
</div>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div class="form-group col-lg-6 col-md-6 col-sm-12">
<form:label path="serviceCategories">Service Categories<em class="mandatory">*</em></form:label>
<div class="col-lg-10 col-md-12 col-sm-12">
<form:select path="serviceCategories" class="selectpicker" multiple="true">
<form:options items="${serviceCategoriesList}" itemValue="id" itemLabel="serviceCatName"/>
</form:select>
<form:errors class="alert alert-danger" path="serviceCategories" />
</div>
<div class="clearfix"></div>
</div>
<div class="form-group col-lg-6 col-md-6 col-sm-12">
<form:label path="employeeImage">Upload Employee Image<em class="mandatory">*</em></form:label>
<div class="col-lg-10 col-md-12 col-sm-12">
<input name="employeeImage" type="file">
<form:errors class="alert alert-danger" path="employeeImage" />
</div>
<div class="clearfix"></div>
</div>
<c:if test="${ACTION == 'Edit'}">
<form:hidden path="employeeImageFileName" />
</c:if>
</div>
<div class="row">
<div class="form-group col-lg-12 col-md-12 col-sm-12">
<!-- <button type="submit" class=" orangebtn btn mtop20">
Submit <i class="fa fa-arrow-circle-right left"></i>
</button> -->
<form:button type="submit" class=" orangebtn btn mtop20">Submit <i class="fa fa-arrow-circle-right left"></i></form:button>
</div>
</div>
</form:form>
</div>
EmployeeController.java
/* This method will be called on form submission, handling POST request for
saving employee in database. It also validates the user input*/
@RequestMapping(value = { "/add" }, method = RequestMethod.POST)
public String saveEmployee(
@Valid @ModelAttribute("employee") Employee employee,
BindingResult result, ModelMap model, Map<String, Object> map,
HttpServletRequest request) {
boolean isError = false;
logger.debug("Entered saveEmployee method");
logger.debug("employee.getEmpFirstName() : "
+ employee.getEmpFirstName());
logger.debug("employee.getEmpLastName() : "
+ employee.getEmpLastName());
logger.debug("employee.getEmpDesignation() : "
+ employee.getEmpDesignation());
logger.debug("employee.getEmployeeImage().getSize() : "
+ employee.getEmployeeImage().getSize());
logger.debug("employee.getEmployeeType() : "
+ employee.getEmployeeType());
logger.debug("employee.getServiceCategories() : "
+ employee.getServiceCategories());
logger.debug("employee.getEmployeeType().getId() : "
+ employee.getEmployeeType().getId());
logger.debug("employee.getServiceCategories().size() : "
+ employee.getServiceCategories().size());
}
当用户提交数据并选择服务类别时,日志中会打印以下内容
DEBUG 2015-08-06 11:07:36,679 [http--127.0.0.1-8080-3] com.abc.controller.EmployeeController - Entered saveEmployee method
DEBUG 2015-08-06 11:07:36,679 [http--127.0.0.1-8080-3] com.abc.controller.EmployeeController - employee.getEmpFirstName() : fsddf
DEBUG 2015-08-06 11:07:36,680 [http--127.0.0.1-8080-3] com.abc.controller.EmployeeController - employee.getEmpLastName() : sdfsdsfdsdf
DEBUG 2015-08-06 11:07:36,680 [http--127.0.0.1-8080-3] com.abc.controller.EmployeeController - employee.getEmpDesignation() : sdfsdfsd
DEBUG 2015-08-06 11:07:36,681 [http--127.0.0.1-8080-3] com.abc.controller.EmployeeController - employee.getEmployeeImage().getSize() : 252227
DEBUG 2015-08-06 11:07:36,681 [http--127.0.0.1-8080-3] com.abc.controller.EmployeeController - employee.getEmployeeType() : com.abc.model.EmployeeType@56261adf
DEBUG 2015-08-06 11:07:36,681 [http--127.0.0.1-8080-3] com.abc.controller.EmployeeController - employee.getServiceCategories() : []
DEBUG 2015-08-06 11:07:36,682 [http--127.0.0.1-8080-3] com.abc.controller.EmployeeController - employee.getEmployeeType().getId() : 1
DEBUG 2015-08-06 11:07:36,682 [http--127.0.0.1-8080-3] com.abc.controller.EmployeeController - employee.getServiceCategories().size() : 0
即使我从视图中选择多个服务类别,我也不确定为什么employee.getServiceCategories()。size()为零。
提前感谢您的帮助。
更新
调试时我也尝试打印BindingResult结果的值,它显示我在日志中跟随
DEBUG 2015-08-06 14:59:20,686 [http--127.0.0.1-8080-4] com.abc.controller.EmployeeController - result : org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'employee' on field 'serviceCategories': rejected value [15,17]; codes [typeMismatch.employee.serviceCategories,typeMismatch.serviceCategories,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employee.serviceCategories,serviceCategories]; arguments []; default message [serviceCategories]]; default message [Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.List' for property 'serviceCategories'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.abc.model.ServiceCategory] for property 'serviceCategories[0]': no matching editors or conversion strategy found]
答案 0 :(得分:0)
发现问题所在。数据绑定存在问题,因为spring无法从serviceCategories变量获得list employee.serviceCategories的值。
我做了一些RnD(主要是参考Spring form binding how to do it ? Cannot convert value of type [java.lang.String] to required type和http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/validation.html#format-configuring-formatting-mvc)并在我的控制器中进行了以下更改
id= <?php echo $detail1[$i]['id'];?>