O erro só ocorre ao inserir sem preencher os dados do form, se preencher e salvar não acontece e salva normalmente.
HTTP Status 500 - org.springframework.beans.NotReadablePropertyException: Invalid property 'produto' of bean class [br.com.casadocodigo.loja.models.Produto]: Bean property 'produto' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
type Exception report
message org.springframework.beans.NotReadablePropertyException: Invalid property 'produto' of bean class [br.com.casadocodigo.loja.models.Produto]: Bean property 'produto' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: org.springframework.beans.NotReadablePropertyException: Invalid property 'produto' of bean class [br.com.casadocodigo.loja.models.Produto]: Bean property 'produto' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:565)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:481)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:172)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
root cause
org.springframework.beans.NotReadablePropertyException: Invalid property 'produto' of bean class [br.com.casadocodigo.loja.models.Produto]: Bean property 'produto' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:705)
org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:551)
org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:528)
org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:694)
org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99)
org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:229)
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:120)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
org.springframework.web.servlet.tags.form.ErrorsTag.shouldRender(ErrorsTag.java:141)
org.springframework.web.servlet.tags.form.AbstractHtmlElementBodyTag.writeTagContent(AbstractHtmlElementBodyTag.java:48)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
org.apache.jsp.WEB_002dINF.views.produtos.form_jsp._jspService(form_jsp.java:176)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:443)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:172)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Livros de Java, Android, iPhone, Ruby, PHP e muito mais -
Casa do Código</title>
</head>
<body>
<form:form action="${s:mvcUrl('PC#gravar').build() }" method="post"
commandName="produto">
<div>
<label>Título</label> <input type="text" name="titulo" />
<form:errors path="produto.titulo" />
</div>
<div>
<label>Descrição</label>
<textarea rows="10" cols="20" name="descricao"></textarea>
<form:errors path="produto.descricao" />
</div>
<div>
<label>Páginas</label> <input type="text" name="paginas" />
<form:errors path="produto.paginas" />
</div>
<c:forEach items="${tipos}" var="tipoPreco" varStatus="status">
<div>
<label>${tipoPreco}</label> <input type="text"
name="precos[${status.index}].valor" /> <input type="hidden"
name="precos[${status.index}].tipo" value="${tipoPreco}" />
</div>
</c:forEach>
<button type="submit">Cadastrar</button>
</form:form>
</body>
</html>
ProdutosController.java
package br.com.casadocodigo.loja.controllers;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import br.com.casadocodigo.loja.daos.ProdutoDAO;
import br.com.casadocodigo.loja.models.Produto;
import br.com.casadocodigo.loja.models.TipoPreco;
import br.com.casadocodigo.loja.validation.ProdutoValidation;
@Controller
@RequestMapping("/produtos")
public class ProdutosController {
@Autowired
private ProdutoDAO produtoDao;
@InitBinder
public void InitBinder(WebDataBinder binder){
binder.addValidators(new ProdutoValidation());
}
@RequestMapping("/form")
public ModelAndView form() {
ModelAndView modelAndView = new ModelAndView("produtos/form");
modelAndView.addObject("tipos", TipoPreco.values());
return modelAndView;
}
@RequestMapping(method=RequestMethod.POST)
public ModelAndView gravar(@Valid Produto produto, BindingResult result, RedirectAttributes redirectAttributes){
if(result.hasErrors()){
return form();
}
produtoDao.gravar(produto);
redirectAttributes.addFlashAttribute("message","Produto cadastrado com sucesso");
return new ModelAndView("redirect:produtos");
}
@RequestMapping(method = RequestMethod.GET)
public ModelAndView listar() {
List<Produto> produtos = produtoDao.listar();
ModelAndView modelAndView = new ModelAndView("produtos/lista");
modelAndView.addObject("produtos", produtos);
return modelAndView;
}
}
Produto.java
package br.com.casadocodigo.loja.models;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Produto {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String titulo;
private String descricao;
private int paginas;
@ElementCollection
private List<Preco> precos;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<Preco> getPrecos() {
return precos;
}
public void setPrecos(List<Preco> precos) {
this.precos = precos;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public int getPaginas() {
return paginas;
}
public void setPaginas(int paginas) {
this.paginas = paginas;
}
@Override
public String toString() {
return "Produto [titulo=" + titulo + ", descricao=" + descricao + ", paginas=" + paginas + "]";
}
}