Spring-从web表单更新OneToMany集合
我正在尝试删除表单中的一个值Spring-从web表单更新OneToMany集合,spring,jpa,Spring,Jpa,我正在尝试删除表单中的一个值 public class Parameter { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "param_id") private Long id; @Column(name = "param_name") @NotEmpty private String name; @OneToMany(cascade =
public class Parameter {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "param_id")
private Long id;
@Column(name = "param_name")
@NotEmpty
private String name;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "param_id", referencedColumnName = "param_id")
private List<ParamValue> values;
}
表格:
在参数值中:
-----------------------------
| id | name | parameter |
-----------------------------
| 116 | value 1 | 3 |
-----------------------------
| 117 | value 2 | 3 |
-----------------------------
| 119 | value 3 | 3 |
-----------------------------
| 152 | value 4 | 3 |
-----------------------------
和控制器:
@Controller(value = "ParamsSave")
@RequestMapping("/params/save")
public class Save extends Base {
@Autowired
private ParamRepo paramRepo;
@ModelAttribute("parameter")
public Parameter getParam(@RequestParam(value = "id", required = false) Long param_id) {
if(param_id == null) {
return new Parameter();
}
Parameter parameter = paramRepo.findById(param_id);
return parameter == null ? new Parameter() : parameter;
}
@GetMapping
public String get(Parameter parameter) {
return getTemplate();
}
@PostMapping
public String post(@Valid Parameter parameter, BindingResult result) {
if(result.hasErrors()) {
return getTemplate();
}
paramRepo.save(parameter);
return "redirect: /";
}
}
如果删除值“值2”,则会出现get错误:
beans.ParamValue实例的标识符从117更改为
119; 嵌套异常是org.hibernate.hibernateeexception:标识符
beans.ParamValue实例的值从117更改为119
若我删除了最后一个值,那个么什么也并没有发生,并没有错误,字段也并没有被删除
为什么会发生这种情况,如何从列表中删除值?我可以看到代码中存在三个问题: 第一,关联映射是错误的。在双向关联中,一方必须是拥有方,另一方必须是反向方。正确的映射如下所示:
@OneToMany(mappedBy = "parameter", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ParamValue> values;
请注意,我还删除了cascade=ALL
,因为它在@ManyToOne
的上下文中毫无意义(例如,您不能将参数值的删除级联到其所属的参数,因为其他参数值仍会引用它,从而导致约束冲突异常)
尽管如此,我对是否需要双向关联持严重怀疑态度。为什么不简单地将参数值映射为:
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "param_id", referencedColumnName = "param_id")
private List<ParamValue> values;
然而,很可能它并没有达到你的期望。在任何情况下,我都不会依赖于在Save.post
处理程序中正确设置ParameterValue.parameter
字段。如果选择保留ParameterValue.parameter
字段,则应迭代parameter.values
列表,并为每个元素手动设置字段
最后,使用$(this).parent().remove()
意味着提交的参数.values[]
数组中会有一个间隙(即,最初与删除的元素对应的索引将丢失),这与您观察到的删除最后一个值的行为不同的观察结果一致。您应该使用调试器检查Save.post
收到的Parameter.values
的内容 删除代码在哪里?
@Controller(value = "ParamsSave")
@RequestMapping("/params/save")
public class Save extends Base {
@Autowired
private ParamRepo paramRepo;
@ModelAttribute("parameter")
public Parameter getParam(@RequestParam(value = "id", required = false) Long param_id) {
if(param_id == null) {
return new Parameter();
}
Parameter parameter = paramRepo.findById(param_id);
return parameter == null ? new Parameter() : parameter;
}
@GetMapping
public String get(Parameter parameter) {
return getTemplate();
}
@PostMapping
public String post(@Valid Parameter parameter, BindingResult result) {
if(result.hasErrors()) {
return getTemplate();
}
paramRepo.save(parameter);
return "redirect: /";
}
}
@OneToMany(mappedBy = "parameter", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ParamValue> values;
@ManyToOne
@JoinColumn(name="param_id")
private Parameter parameter;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "param_id", referencedColumnName = "param_id")
private List<ParamValue> values;
<form:input path="values[${uStatus.index}].parameter" type="hidden" />