如何在多对多字段中实现视图?

How to implement the view in a manyToMany field?

任何人都成功地实现了 html 查看 manyToMany 字段,比如那个:

  @ManyToMany
  @JoinTable(name="listaDeProdutosEmDestaque", joinColumns={@JoinColumn(name="fk_destaque")}, inverseJoinColumns={@JoinColumn(name="fk_produto")})
  @LazyCollection(LazyCollectionOption.FALSE)
  private List<Produto> listaDeProdutos;

我已经尝试过这些选项,但都不起作用:

<select class="form-control" name="listaDeProdutos[]" multiple="multiple" rows="7">
    ...
    <option value="1">one</option>
    ...
</select>

我收到错误:NumberFormatException: For input string: ""

<select class="form-control" name="listaDeProdutos" multiple="multiple" rows="7">
    ...
    <option value="1">one</option>
    ...
</select>

表单提交没有错误,但数据库中没有存储任何选择的选项

<select class="form-control" name="listaDeProdutos.id" multiple="multiple" rows="7">
    ...
    <option value="1">one</option>
    ...
</select>

与之前相同:表单提交无误,但数据库中未存储任何数据。

更新

表单提交由这个 controller/service 方法处理:

--控制器类

  @RequestMapping(value = "cadastra", method=RequestMethod.POST)
  @ResponseBody
  public void cadastra(@ModelAttribute("object") E object, BindingResult result, @RequestParam(value="icone", required=false) MultipartFile icone, @RequestParam(value="fotos", required=false) MultipartFile fotos[], @RequestParam(value="arquivo", required=false) MultipartFile arquivo[]) throws Exception {
    serv.cadastra(object);
    serv.upload(object, icone);
    serv.upload_multiplo(object, fotos);
    serv.upload_jar(object, arquivo);
  }

--服务等级

  @PreAuthorize("hasPermission(#user, 'cadastra_'+#this.this.name)")
  @Transactional
  public void cadastra(E object) {
    dao.insert(object);
  }

视图是这样映射的:

--控制器类

  @RequestMapping(value = "cadastra")
  @PreAuthorize("hasPermission(#user, 'cadastra_'+#this.this.name)")
  @Menu(label = "cadastra")
  public String cadastra(Model model) throws Exception {
    model.addAttribute("command", serv.newObject());
    return "private/cadastra";
  }

--服务等级

  public E newObject() throws Exception {
    return (E) clazz.newInstance();
  }

更新 2

在控制器中:

  @InitBinder
  public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Pagina.class, new PaginaEditor());
    binder.registerCustomEditor(Produto.class, new ProdutoEditor());
  }

属性编辑器类:

@Component
public class ProdutoEditor extends PropertyEditorSupport {
  @Autowired
  private ProdutoService produtoService;

  @Override
  public void setAsText(String text) {
    System.out.println("produtoEditor");
    if (!text.equals("")) {
      System.out.println("not empty");
      Produto produto = produtoService.getObject(text);
      setValue(produto);
    } else {
      System.out.println("empty");
      setValue(null);
    }
  }
}

尝试

<select class="form-control" name="listaDeProdutos[0].id" rows="7">
    ...
    <option value="1">one</option>
    ...
</select>

只是为了在索引 0 处添加一个,然后通过 javascript 处理正确的 indexes/values 和 adding/removing 一个 select 下拉列表。

反正你也可以试试这个:

<select class="form-control" name="listaDeProdutos[].id" multiple="multiple" rows="7">
    ...
    <option value="1">one</option>
    ...
</select>

我设法解决了这个问题,将 属性 编辑器 class 更改为:

@Component
public class ProdutoEditor extends PropertyEditorSupport {
  @Override
  public void setAsText(String text) {
    if (!text.equals("")) {
      ProdutoService serv = new ProdutoService();
      ApplicationContextHolder.getContext().getAutowireCapableBeanFactory().autowireBean(serv);
      Produto produto = serv.getObject(text);
      setValue(produto);
    } else {
      setValue(null);
    }
  }
}

使用此 select 代码:

<select class="form-control" name="listaDeProdutos" multiple="multiple" rows="7">
    ...
    <option value="1">one</option>
    ...
</select>