我有一个创建新办公室的MVC应用程序,而不是在使用编辑表单时更新它们。请帮助我理解为什么会这样。
填充搜索结果的搜索方法:
@RequestMapping(value = "/searchResults", method = RequestMethod.POST)
public ModelAndView search(@RequestParam String searchCriteria, HttpServletRequest request) {
List<Office> offices = officeServiceImpl.search(searchCriteria);
return new ModelAndView("searchResults", "offices", offices);
}
以下是搜索结果页面上编辑表单的链接:
<a href="${pageContext.request.contextPath}/app/office/${office.getId()}/edit" class="btn btn-success">Edit Office</a>
以下是Controller的编辑GET方法,该方法使用现有Office填充表单:
@RequestMapping(value = "/{officeId}/edit", method = RequestMethod.GET)
@Transactional(noRollbackFor=NoResultException.class)
public ModelAndView initUpdateOfficeForm(
@PathVariable("officeId") Long officeId, Model model) {
Office office = officeServiceImpl.find(officeId);
//prepareEditFormModelAndView(office) just converts some objects to strings for typeahead form population
return prepareEditFormModelAndView(office);
}
这是编辑POST方法:
@RequestMapping(value = "/{officeId}/edit", method = RequestMethod.POST)
public ModelAndView processUpdateOfficeForm(@ModelAttribute("office") @Valid Office office,
BindingResult result, SessionStatus status) {
if (! "united states of america".equals(office.getFolderStrings().toLowerCase())) {
//This portion of code converts the typeahead strings to objects
result = tryCountries(office, result);
result = tryDepartments(office, result);
result = tryEmployees(office, result);
}
if (result.hasErrors()) {
return prepareEditFormModelAndView(office);
} else {
officeServiceImpl.save(office);
status.setComplete();
return new ModelAndView("editResult", "office", office);
}
}
officeServiceImpl调用officeRepositoryImpl方法保存,如下所示:
@Override
public Office save(Office office) {
em.merge(office);
em.flush();
return office;
}
由于
编辑:添加prepareEditFormModelAndView(office),此方法尝试从关联对象构建字符串:
@Transactional(noRollbackFor={NoResultException.class, IndexOutOfBoundsException.class})
private ModelAndView prepareEditFormModelAndView(Office office) {
String departmentStrings = "";
String employeeStrings = "";
List<OOM> officeOOMs = new ArrayList<OOM>();
StringBuilder sb = new StringBuilder();
try {
officeOOMs = oomServiceImpl.getOOMsForCurrentOffice(office.getId());
} catch (NoResultException e) {
officeOOMs = null;
}
for (OOM o : officeOOMs) {
try {
Employee tempEmployee = employeeServiceImpl.find(o
.getEmployeeId());
sb.append(tempEmployee.getDisplayName() + ", ");
} catch (NoResultException e) {
sb.append("Not found in system");
}
}
employeeStrings = sb.toString();
if ((! "".equals(office.getDepartmentStringsOnForm())) && office.getDepartmentStringsOnForm() != null) {
departmentStrings = office.getDepartmentStringsOnForm();
}
String folderStrings = "";
try {
folderStrings = kmlFolderServiceImpl.getInternationalOfficeString(office.getId());
LOGGER.info("Folder Strings: " + folderStrings);
} catch (NoResultException e) {
folderStrings = "";
LOGGER.info("Folder Strings: " + "no result");
}
boolean isInternational = office.isInternational();
ModelAndView result = new ModelAndView("editOfficeForm", "office", office);
result.addObject("departmentStrings", departmentStrings);
result.addObject("isInternational", isInternational);
result.addObject("folderStrings", folderStrings);
result.addObject("employeeStrings", employeeStrings);
return result;
}
答案 0 :(得分:2)
我在此处添加了之前的评论,以便更好地澄清。根据OP,以下问题解决了这个问题:
当ID不在表单中时,当模型被回发时,没有为实体设置ID,使得持久性提供者认为它是新实体。 因此,最明显的解决方案是在保存操作中发布实体的ID(可能使用隐藏字段)。
另一种解决方案是尝试根据某些业务密钥在数据库中加载实体 查看实体是否是新的。