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

Adicionar Data e Hora

Olá. Estou com um projeto de CRUD e gostaria que o objeto que esta sendo gerenciado, tivesse registrado a data e hora em que ele foi adicionado ao sistema. Logo, com essa ideia em mente fiz o seguinte:

@Entity
public class Visitante {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    public int id;

    public String nome;
    public String documento;
    public String placa;
    public String destino;
    @Temporal(TemporalType.TIMESTAMP)
    public Calendar dataHora;
    ...
    ...
    ...
    public Calendar getDataHora() {
        return dataHora;
    }
    public void setDataHora(Calendar dataHora) {
        this.dataHora = dataHora;
    }
    public Visitante(String nome, String documento, String placa, String destino, Date dataHora) {
        this.nome = nome;
        this.documento = documento;
        this.placa = placa;
        this.destino = destino;
        setDataHora(Calendar.getInstance());
    }
}

Acredito que seja algo parecido com isso. Porém após cadastrar um novo objeto, quando vou acessar meu BD, o campo: "datahora timestamp without timezone" foi criado, porém está vazio.

9 respostas

Boa tarde, Felipe! Como vai?

Vc tbm tem um construtor padrão (vazio) na sua classe, certo? Se sim, vc lembrou de setar o atributo dataHora no objeto que vc tentou salvar no BD?

Olá, Gabriel. Possuo sim um construtor padrão. N entendi sobre a parte de setar o atributo dataHora no objeto. Vc ta se referindo ao:

    public Visitante(String nome, String documento, String placa, String destino, Date dataHora) {
[...]
        setDataHora(Calendar.getInstance());
    }

?

Não, Felipe! Essa parte do construtor eu vi! O que eu imagino que esteja acontecendo é que o seu construtor padrão esteja sendo usado para construir o objeto e que, após isso, vc não esteja colocando uma data no seu objeto que vai ser persistido.

De onde os dados estão vindo? De uma tela JSP e eles estão sendo injetados pelo Spring na sua action?

Se for isso, cole aqui o código da sua página JSP, da action que é acionada no envio dos dados e do método responsável por salvar os dados no BD.

Obrigado, Gabriel. Sim, está vindo de uma JSP

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ include file="/WEB-INF/views/cabecalho.jsp"%>

<c:url value="/" var="contextPath" />

    <div class="container">
        <h1>Cadastro de Visitantes</h1>
        <form:form action="${s:mvcUrl('VC#grava').build() }" method="POST" modelAttribute="visitante" enctype="multipart/form-data">
            <div class="form-group">
                <label>Nome</label>
                <form:input path="nome" cssClass="form-control" />
                <form:errors path="nome" />
            </div>
            <div class="form-group">
                <label>Documento</label>
                <form:input path="documento" cssClass="form-control" />
                <form:errors path="documento" />
            </div>
            <div class="form-group">
                <label>Placa do Veículo</label>
                <form:input path="placa" cssClass="form-control" />
                <form:errors path="placa" />
            </div>
            <div class="form-group">
                <label>Destino de Visita</label>
                <form:input path="destino" cssClass="form-control" />
                <form:errors path="destino" />
            </div>
            <div class="form-group">
                <label>Foto</label><input type="file" name="fotoPath" class="form-control" />
            </div>
            <button type="submit" class="btn btn-primary">Cadastrar</button>
        </form:form>
    </div>
<%@ include file="/WEB-INF/views/rodape.jsp"%>

Uma coisa q eu observei foi q o projeto final de Spring MVC 2 não possui nenhum construtor dentro da classe modelo: Produto. Qual a razão?

Felipe, vc esqueceu de colar aqui a action do Spring que é acionada quando vc envia o formulário. Eu acho que já sei o que está acontecendo, mas preciso ver a action pra ter certeza.

Obs.: Responderei todas as suas perguntas, incluindo essa do construtor, no final!

Olá, Gabriel. Vc se refere ao metodo grava() no controller?

@RequestMapping(method=RequestMethod.POST)
    public ModelAndView grava(MultipartFile fotoPath, @Valid Visitante visitante, BindingResult result, RedirectAttributes redirectAttributes) {

        if(result.hasErrors()){
            System.out.println("TEM ERRO");
            return form(visitante);
        }

        if (fotoPath != null && !fotoPath.getOriginalFilename().isEmpty()) {
            String path = fileSaver.write("fotosPasta", fotoPath);
            visitante.setfotoPath(path);
        }

        visitanteDao.gravar(visitante);
        redirectAttributes.addFlashAttribute("sucesso", "Visitante Cadastrado com Sucesso");
        return new ModelAndView("redirect:/visitantes");
    }
solução!

Opa, Felipe! Agora sim!

O problema é que o encarregado de instânciar um objeto Visitante é o Spring! E o Spring não coloca uma data no atributo Calendar dataHora da sua classe pq ele executa o construtor padrão (vazio) da sua classe! Por isso que seu objeto está indo para o BD sem data, afinal de contas ninguém seta uma data, nem vc e nem o Spring como eu disse inicialmente.

Para resolver o seu problema, faz o seguinte:

@RequestMapping(method=RequestMethod.POST)
public ModelAndView grava(MultipartFile fotoPath, @Valid Visitante visitante, BindingResult result, RedirectAttributes redirectAttributes) {

        // código anterior omitido

        visitante.setDataHora(Calendar.getInstance());

        visitanteDao.gravar(visitante);
        redirectAttributes.addFlashAttribute("sucesso", "Visitante Cadastrado com Sucesso");
        return new ModelAndView("redirect:/visitantes");
    }

O motivo das classe de modelo não terem nenhum construtor é pq a criação dos objetos será feita pelo Spring e ele usa o construtor padrão, além disso, o Hibernate tbm precisa do construtor padrão para conseguir trabalhar. Ou seja, já que essas ferramentas que utilizamos precisam do construtor padrão para trabalhar com os objetos de nossas classes modelo, normalmente deixamos essas classes apenas com seus atributos, os getters e os setters.

Entendido? Qualquer coisa é só falar!

Grande abraço e bons estudos!

Entendi perfeitamente, Gabriel. Muito obrigado pelos esclarecimentos. Acabei de setar na classe spring e funcionou perfeitamente. Eu ainda possuo outras duvidas, é em relação ao validation. Porém acho q seria melhor abrir outro tópico, já q esse já foi resolvido. Parabéns, Grabriel.

Mto bem, Felipe!

Isso, o ideal é dividir as dúvidas por tópicos! Fique a vontade para procurar o pessoal aqui no fórum sempre que necessário!

Grande abraço e bons estudos!