我在尝试将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();
}