Problemas com conversão de tipos Date e String - O Spring ficou doido! [RESOLVIDO]

Bom Dia Senhores… estou fazendo uma pequena aplicação utilizando SpringMVC e o Oracle, nesta aplicação eu criei uma Classe Processo, onde nesta classe existem dois atributos, os quais são:

private Calendar dataAbertura;
private Calendar dataFechamento;

Ocorre que o Spring (me parece) não consegue converter em Date, esperando assim uma String para popular o objeto e persistir no Oracle… segue o Erro:

Grave: Servlet.service() for servlet [springMVC] in context with path [/projeto-am-sysJur-springMVC] threw exception [Request processing failed; nested exception is org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'processo' on field 'dataAbertura': rejected value [01/02/2013]; codes [typeMismatch.processo.dataAbertura,typeMismatch.dataAbertura,typeMismatch.java.util.Calendar,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [processo.dataAbertura,dataAbertura]; arguments []; default message [dataAbertura]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Calendar' for property 'dataAbertura'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Calendar] for property 'dataAbertura': no matching editors or conversion strategy found]] with root cause
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'processo' on field 'dataAbertura': rejected value [01/02/2013]; codes [typeMismatch.processo.dataAbertura,typeMismatch.dataAbertura,typeMismatch.java.util.Calendar,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [processo.dataAbertura,dataAbertura]; arguments []; default message [dataAbertura]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Calendar' for property 'dataAbertura'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Calendar] for property 'dataAbertura': no matching editors or conversion strategy found]
	at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:810)

Fiz um teste mudando estes dois atributos, ou seja mudei de Calendar para String e onde estava assim:

private Calendar dataAbertura;
private Calendar dataFechamento;

ficou assim:

private String dataAbertura;
private String dataFechamento;

Mas confesso que, pra mim, é meio indigesto trabalhar com datas utilizando o tipo primitivo String! (rs) - Se alguém já passou por isso e puder ajudar… agradeço desde já!

Abraços e Feliz 2013!

Creio que você precise criar algum tipo de conversor. Nunca usei SpringMVC mas creio que esse post resolva seu problema:

É eu tive vendo essa conversão em um outro site (http://www.roseindia.net/tutorial/spring/spring3/ioc/springvalidation.html), mas o que é mais engraçado é que eu acabei de terminar um projetinho com Spring e nele utilizei o Calendar sem problema algum… vai entender esses framewoks! rs mas valeu, o jeito é apelar para essa conversão mesmo!

O Spring MVC precisa de um conversor, até tem um nele, mas esse converte para java.util.Date, e no seu caso como precisa de um Calendar, vai precisar fazer o seu próprio.

Senhores está resolvido o problema agradeço a todos… o que estava faltando era a anotação do Spring no atributo da Classe, como segue abaixo:


@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataAbertura;
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataFechamento;

Essa anotação informa o framework que tal atributo trata-se de um Calendar ou Date…

Obrigado a todos… mas esse problema pelo menos aqui no GUJ, não tinha solução!

[quote=ppro11]Senhores está resolvido o problema agradeço a todos… o que estava faltando era a anotação do Spring no atributo da Classe, como segue abaixo:


@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataAbertura;
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Calendar dataFechamento;

Essa anotação informa o framework que tal atributo trata-se de um Calendar ou Date…

Obrigado a todos… mas esse problema pelo menos aqui no GUJ, não tinha solução!

[/quote]

Não conhecia essa anotação, pelo menos não como conversor, achei que ela funcionava apenas para uso do Validator.
Legal saber.

Pessoal, estou usando a mesma configuração para validar o formato da data, só não está 100%. Vejam como fiz:

Classe Empresa entity:

@Column(name="data_baixa")
@DateTimeFormat(pattern="dd/MM/yyyy")
//@Pattern(regexp = "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)")
//@Temporal(TemporalType.DATE)
private Date dataBaixa;

...

Meu controller metodo salvar:

@RequestMapping(value = "/cadastros/empresas", method = RequestMethod.POST)
	public String salvaEmpresa(@ModelAttribute("empresa") @Valid Empresa empresa, BindingResult result) {
				
		if (!result.hasErrors()){
			empresaDao.salvar(empresa);			
			return "redirect:/cadastros/empresas";
		} else {
			return "cadastros/empresas/create";
		}

	}

@InitBinder
protected void initBinder(WebDataBinder binder) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true) );
    //binder.setValidator(validator);
}

Na view:

<form:input cssStyle="width:250px" maxlength="20" path="dataBaixa" size="10" cssClass="fieldGrid" id="dataInclusao" />

Só que o problema é como validar a data em si. Tipo: se eu colocar 40/13/2013 o sistema até salva, mas com uma data futura bem diferente.
Tentei usar um regexp para isso, conforme comentado, mas não tive sucesso:
Ocorre o erro: javax.validation.UnexpectedTypeException: No validator could be found for type: java.util.Date

Sou novo no spring, alguém sabe como posso validar a data em si com o framework?

Grato.

Buenas, pelo que vi, se utilizar junto o @temporal(TemporalType.DATE), uma validação é feita nos moldes que gostaria:

@Column(name="data_baixa")  
@DateTimeFormat(pattern="dd/MM/yyyy")  
//@Pattern(regexp = "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)")  
@Temporal(TemporalType.DATE)  
private Date dataBaixa;  

Porém, por se tratar de uma validação do javax.persistence, ao informar uma data como 10/10/10001 ela não é tratada na propria tela como os alertas das anottations exe: org.hibernate.validator.constraint.NotEmpty que fiz utilizando messages.properties

Recebo um HTTP Status 500 - org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.DataException: Only dates between January 1, 1753 and December 31, 9999 are accepted.; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.DataException: Only dates between January 1, 1753 and December 31, 9999 are accepted.

Gostaria de tratá-la da mesma forma que a annotation notEmpty.