Spring MVC,尝试编辑但创建新对象

时间:2014-03-31 13:53:59

标签: java spring spring-mvc

我有一个创建新办公室的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;
}

1 个答案:

答案 0 :(得分:2)

我在此处添加了之前的评论,以便更好地澄清。根据OP,以下问题解决了这个问题:

当ID不在表单中时,当模型被回发时,没有为实体设置ID,使得持久性提供者认为它是新实体。 因此,最明显的解决方案是在保存操作中发布实体的ID(可能使用隐藏字段)。

另一种解决方案是尝试根据某些业务密钥在数据库中加载实体 查看实体是否是新的。