spring + thymeleaf - 如何将一个Set实体分配给另一个?

时间:2016-07-22 02:07:52

标签: spring thymeleaf

我在尝试将Set<Structure>实体与Contract实体关联时遇到了可怕的时间(详见下文)。

在HTML上,duallist选择框是:

            <select multiple="multiple" id="selectedStructures" th:field="*{structures}" name="structures" class="form-control">
                <option th:each="structure : ${allStructures}" 
                        th:value="${{structure.id}}"
                        th:selected="${allStructures.contains(structure)}"
                        th:text="${structure.description}">
                </option>
            </select>

在我的控制器上,此页面的GET和POST方法是:

@RequestMapping(value = "/contract/assignStructure", method = RequestMethod.GET)
public void assignStructure(ModelMap model,
        @RequestParam(value = "contractId", required = true) String contractId) {
    ContractPojo pojo = populatePojoFromContract(contractService.findById(contractId));

    model.addAttribute("pojo", pojo);
    model.addAttribute("allStructures", populateStructurePojoList());
}

@RequestMapping(value = "/contract/assignStructure", method = RequestMethod.POST)
public String assignStructurePost(@Valid @ModelAttribute("pojo") ContractPojo pojo, BindingResult result,
        ModelMap model, Errors errors, final RedirectAttributes redirectAttributes) throws IOException, Exception {

    // pojo.getStructures() bellow is always null...
    Set<Structure> structures = buildContractStructureSet(pojo.getStructures());

    if (errors.hasErrors()) {
        for (ObjectError error : errors.getAllErrors()) {
            System.out.println(error.getDefaultMessage());
        }
        model.addAttribute("pojo", pojo);
        model.addAttribute("allStructures", populateStructurePojoList());
        return "/contract/assignStructures?id=" + pojo.getId();
    }

    try {
        contractService.updateContract(pojo.getId(), 
                                       pojo.getCode(), 
                                       pojo.getDescription(), 
                                       pojo.getStartDate(), 
                                       pojo.getEndDate(), 
                                       contractService.findClientById(pojo.getClientId()).getId(), 
                                       structures);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    model.addAttribute("lastAction", "Structures " + pojo.getStructures() + " have been registered successfully");
    return "redirect:/contract/listStructures?id=" + pojo.getId();
}

我的ContractPojo DTO是:

public class ContractPojo {

    private String id;

    // non relevant attributes

    private List<Structure> structures;

    // getters and setters

我的Contract POJO的相关部分是:

public class Contract extends BasePojo {

    // inherited from BasePojo
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @Column(name = "id", unique = true, insertable = true)
    private String id;

    // non relevant attributes

    @ManyToMany(fetch = FetchType.EAGER)
    @Fetch(FetchMode.SELECT)
    @JoinTable(name = "joinTable_contractStructure", 
            joinColumns = { @JoinColumn(name = "contractId", referencedColumnName="id") },
            inverseJoinColumns = { @JoinColumn(name = "structureId", referencedColumnName="id") })
    private Set<Structure> structures;

    // getters and setters

另外,在我的控制器上,我有两种方法从Set<Structure>来回转换为List<Structure>。他们是:

protected List<Structure> buildStructurePojoList(Contract contract) {
    List<Structure> pojoList = new ArrayList<Structure>();
        if (contract.getStructures() != null) {
            for (Structure structure : contract.getStructures()) {
                pojoList.add(structure);
            } 
        }
    return pojoList;
}

protected Set<Structure> buildContractStructureSet(List<Structure> structures) {
    Set<Structure> set = new HashSet<Structure>();
    if (structures != null) {
        for (Structure pojo : structures) {
            set.add(contractService.findStructureById(pojo.getId()));
        }
    }
    return set;
}

调试,我发现我在上面的POST方法中从页面上获得了一个空列表,并且我在控制台上遇到的错误是:

java.lang.IllegalArgumentException: id to load is required for loading
    at org.hibernate.event.spi.LoadEvent.<init>(LoadEvent.java:109)
    at org.hibernate.event.spi.LoadEvent.<init>(LoadEvent.java:79)
    at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2548)
    (...)

但是我没有看到这里发生了什么。我没看到什么?

@RequestMapping(value = "/contract/assignStructure", method = RequestMethod.POST)
public String assignStructurePost(@Valid @ModelAttribute("pojo") ContractPojo pojo, BindingResult result,
        ModelMap model, Errors errors, final RedirectAttributes redirectAttributes) throws IOException, Exception {


    Set<Structure> structures = buildContractStructureSet(pojo.getStructures());

    if (errors.hasErrors()) {
        for (ObjectError error : errors.getAllErrors()) {
            System.out.println(error.getDefaultMessage());
        }
        model.addAttribute("pojo", pojo);
        model.addAttribute("allStructures", populateStructurePojoList());
        return "/contract/assignStructures?id=" + pojo.getId();
    }

    Contract contract = contractService.findById(pojo.getId());

    try {
        contractService.updateContract(contract.getId(), 
                                       contract.getCode(), 
                                       contract.getDescription(), 
                                       contract.getStartDate(), 
                                       contract.getEndDate(), 
                                       contract.getClient().getId(), 
                                       structures);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
    model.addAttribute("lastAction", "Structures " + pojo.getStructures() + " have been registered successfully");
    return "redirect:/contract/listStructures?id=" + pojo.getId();
}

0 个答案:

没有答案