Estou utilizando Spring-data
e Thymeleaf
na minha aplicação, e quando tento submeter um formulário com campo do tipo Date
sem preenchê-lo, obtenho o seguinte erro:
Failed to convert property value of type ‘java.lang.String’ to required type ‘java.util.Date’…
Acredito que é por causa do form enviar o campo data com valor vazio ao invés de nulo. Existe a possibilidade de enviar o valor nulo ao invés de vazio?
Segue alguns trechos do meu código: Classe person:
@Entity @Table(name = "person") public class Person implements Serializable, EnableDisable, GenerateId{ private static final long serialVersionUID = -7232054300548386801L; @Id @Column(name = "person_id") private String personId; @Column(name = "cpf") @Length(min=14, message="{person.min.value.cpf}") @Length(max=14, message="{person.max.value.cpf}") private String cpf; @Column(name = "name") @NotEmpty(message = "{person.empty.value.name}") @Length(min=3, message="{person.min.value.name}") @Length(max=255, message="{person.max.value.name}") private String name; @Column(name = "last_name") @NotEmpty(message = "{person.empty.value.lastname}") @Length(min=3, message="{person.min.value.lastname}") @Length(max=255, message="{person.max.value.lastname}") private String lastName; @Column(name ="date_of_birth",nullable = true) @Temporal(TemporalType.DATE) private Date dateOfBirth; @Column(name = "active") private boolean active; @Column(name = "dweller") private boolean dweller; //morador @Column(name = "owner") private boolean owner; //proprietário @Column(name = "renter") private boolean renter; //locatário @Column(name = "managerCondo") private boolean managerCondo; //Síndico //relationship @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "person_telephone", joinColumns = @JoinColumn(name = "person_id"), inverseJoinColumns = @JoinColumn(name = "telephone_id")) private List<Telephone> telephones; //relationship @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "person_address", joinColumns = @JoinColumn(name = "person_id"), inverseJoinColumns = @JoinColumn(name = "address_id")) private List<Address> addresses; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name="user_id", referencedColumnName="user_id") private User user; public String getPersonId() { return personId; } public String getCpf() { return cpf; } public void setCpf(String cpf) { this.cpf = cpf; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } public boolean isDweller() { return dweller; } public void setDweller(boolean dweller) { this.dweller = dweller; } public boolean isOwner() { return owner; } public void setOwner(boolean owner) { this.owner = owner; } public boolean isRenter() { return renter; } public void setRenter(boolean renter) { this.renter = renter; } public boolean isManagerCondo() { return managerCondo; } public void setManagerCondo(boolean managerCondo) { this.managerCondo = managerCondo; } public List<Telephone> getTelephones() { return telephones; } public void setTelephones(List<Telephone> telephones) { this.telephones = telephones; } public List<Address> getAddresses() { return addresses; } public void setAddresses(List<Address> addresses) { this.addresses = addresses; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Date getDateOfBirth() { return dateOfBirth; } public void setDateOfBirth(Date dateOfBirth) { this.dateOfBirth = dateOfBirth; } public Person() { enable(); generateId(); this.telephones = new ArrayList<Telephone>(); this.addresses = new ArrayList<Address>(); } @Override public void generateId() { if(this.personId == null) { this.personId = UUID.randomUUID().toString(); } } @Override public void enable() { this.active = true; } @Override public void disable() { this.active = false; } }
minha página html:
<form class="col s12" method="post" th:object="$ {person}"> <div class="card-panel"> <label class="" th:text="#{person-data}"></label> <div class="card-panel"> <div class="row"> <div class="input-field col s12 m6 l6"> <input type="hidden" readonly="readonly" th:field="*{personId}" /> <input id="first_name" type="text" class="validate" th:field="*{name}"> <label for="first_name" th:text="#{first-name}"></label> <span th:if="$ {#fields.hasErrors('name')}" th:errors="*{name}" class="validation-message"></span> </div> <div class="input-field col s12 m6 l6"> <input id="last_name" type="text" class="validate" th:field="*{lastName}"> <label for="last_name" th:text="#{last-name}"></label> <span th:if="$ {#fields.hasErrors('lastName')}" th:errors="*{lastName}" class="validation-message"></span> </div> </div> <div class="row"> <div class="input-field col s12 m5 l5"> <i class="material-icons prefix">email</i> <input id="managerCondo-email" type="text" class="validate" th:field="*{user.email}"> <label for="managerCondo-email" th:text="#{email}"></label> <span th:if="$ {#fields.hasErrors('user.email')}" th:errors="*{user.email}" class="validation-message"></span> </div> <div class="input-field col s12 m5 l5"> <i class="material-icons prefix">cake</i> <input type="text" class="datepicker validate" th:field="*{dateOfBirth}"> <label for="dateOfBirth" th:text="#{date.birth}"></label> <span th:if="$ {#fields.hasErrors('dateOfBirth')}" th:errors="*{dateOfBirth}" class="validation-message"></span> </div> </div> </div> <label th:text="#{address}"></label> <div th:replace="/fragments/addresses::addresses"></div> <label th:text="#{condo-telephones}"></label> <div th:replace="/fragments/telephones::telephones"></div> <div th:replace="/fragments/buttons::button-save-person-profile"></div> </div> </form>
O erro ao enviar o form com o campo data vazio
Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Sun Jul 28 22:16:56 BRT 2019 There was an unexpected error (type=Bad Request, status=400). Validation failed for object='person'. Error count: 1 org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'person' on field 'dateOfBirth': rejected value []; codes [typeMismatch.person.dateOfBirth,typeMismatch.dateOfBirth,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.dateOfBirth,dateOfBirth]; arguments []; default message [dateOfBirth]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'dateOfBirth'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@javax.persistence.Column @javax.persistence.Temporal java.util.Date] for value ''; nested exception is java.lang.IllegalArgumentException] at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:164) at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:126) at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:166) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908) at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:320) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$ VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ ConnectionHandler.process(AbstractProtocol.java:834) at org.apache.tomcat.util.net.NioEndpoint$ SocketProcessor.doRun(NioEndpoint.java:1415) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$ Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$ WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source)