Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring-从web表单更新OneToMany集合_Spring_Jpa - Fatal编程技术网

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" />