Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

typeMismatch usando a tag form:hidden do spring

Segui as instruções do vídeo, mas ao usar a tag form: hidden do spring o cadastro não é feito com sucesso e retorna para o form.

<c:forEach items="${tipos}" var="tipoPreco" varStatus="status">
    <div>
        <label for="preco${status.index}">Preço ${tipoPreco.toString()}</label>
        <form:input path="precos[${status.index}].valor" id="preco${status.index}" />
        <form:hidden path="precos[${status.index}].tipo" value="${tipoPreco}" />
    </div>
</c:forEach>

Para tentar descobrir, coloquei para escrever no console os resultados do erros de binding:

@RequestMapping(method = RequestMethod.POST)
    public ModelAndView gravar(@Valid Produto produto, BindingResult bindingResult,
                               RedirectAttributes redirectAttributes) {

        if (bindingResult.hasErrors()) {
            for (ObjectError oe : bindingResult.getAllErrors()) {
                System.out.println(oe.toString());
            }
            return form(produto);
        }

        produtoDAO.gravar(produto);
        redirectAttributes.addFlashAttribute("mensagem", "Produto cadastrado com sucesso!");

        return new ModelAndView("redirect:produtos");
    }

E o que aparece no console é isso:

Field error in object 'produto' on field 'precos[0].tipo': rejected value [E-book]; codes [typeMismatch.produto.precos[0].tipo,typeMismatch.produto.precos.tipo,typeMismatch.precos[0].tipo,typeMismatch.precos.tipo,typeMismatch.tipo,typeMismatch.br.com.casadocodigo.loja.models.TipoPreco,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [produto.precos[0].tipo,precos[0].tipo]; arguments []; default message [precos[0].tipo]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'br.com.casadocodigo.loja.models.TipoPreco' for property 'precos[0].tipo'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type br.com.casadocodigo.loja.models.TipoPreco for value 'E-book'; nested exception is java.lang.IllegalArgumentException: No enum constant br.com.casadocodigo.loja.models.TipoPreco.E-book]
Field error in object 'produto' on field 'precos[1].tipo': rejected value [Impresso]; codes [typeMismatch.produto.precos[1].tipo,typeMismatch.produto.precos.tipo,typeMismatch.precos[1].tipo,typeMismatch.precos.tipo,typeMismatch.tipo,typeMismatch.br.com.casadocodigo.loja.models.TipoPreco,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [produto.precos[1].tipo,precos[1].tipo]; arguments []; default message [precos[1].tipo]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'br.com.casadocodigo.loja.models.TipoPreco' for property 'precos[1].tipo'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type br.com.casadocodigo.loja.models.TipoPreco for value 'Impresso'; nested exception is java.lang.IllegalArgumentException: No enum constant br.com.casadocodigo.loja.models.TipoPreco.Impresso]
Field error in object 'produto' on field 'precos[2].tipo': rejected value [E-book + Impresso]; codes [typeMismatch.produto.precos[2].tipo,typeMismatch.produto.precos.tipo,typeMismatch.precos[2].tipo,typeMismatch.precos.tipo,typeMismatch.tipo,typeMismatch.br.com.casadocodigo.loja.models.TipoPreco,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [produto.precos[2].tipo,precos[2].tipo]; arguments []; default message [precos[2].tipo]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'br.com.casadocodigo.loja.models.TipoPreco' for property 'precos[2].tipo'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type br.com.casadocodigo.loja.models.TipoPreco for value 'E-book + Impresso'; nested exception is java.lang.IllegalArgumentException: No enum constant br.com.casadocodigo.loja.models.TipoPreco.E-book + Impresso]

Se eu não usar as tags form:* do spring o cadastro funciona sem problemas. Alguma idéia do que pode estar ocorrendo?

2 respostas
solução!

Desculpa o trabalho aí pessoal... Descobri o problema:

Meu enum TipoPreco antes estava assim:

public enum TipoPreco {

    EBOOK("E-book"),
    IMPRESSO("Impresso"),
    COMBO("E-book + Impresso");

    private String descricao;

    private TipoPreco(String descricao) {
        this.descricao = descricao;
    }

    @Override
    public String toString() {
        return descricao;
    }
}

E na view ficava assim, pra exibir um texto mais apresentável:

<label for="preco${status.index}">Preço ${tipoPreco.toString()}</label>

Removi o método toString do enum e atualizei a view e voltou a funcionar!

public enum TipoPreco {

    EBOOK("E-book"),
    IMPRESSO("Impresso"),
    COMBO("E-book + Impresso");

    private String descricao;

    private TipoPreco(String descricao) {
        this.descricao = descricao;
    }

    public String getDescricao() {
        return descricao;
    }
}
<label for="preco${status.index}">Preço ${tipoPreco.getDescricao()}</label>

Olá Stevie,

Obrigado por registrar aqui a solução para o pessoal poder ver. Mandou bem!

Ah! Como seu método voltou a seguir um padrão getter você ainda poderia inferir a ele na EL apenas com ${tipoPreco.descricao} =P

Abraço!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software