Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
23
respostas

Bloquear alteração na data de cadastro

Boa tarde pessoal!

Na minha classe modelo, eu pego a data do sistema e adiciono no campo data_cadastro...

Porém quando eu altero um registro o sistema sobrepõe a data de cadastro, atualizando a mesma...

Minha classe modelo:

    @NotNull
    @Temporal(TemporalType.DATE)
    @Column(name = "data_cadastro")
    private Date dataCadastro = new Date(System.currentTimeMillis());
`´`

Meu método no DAO:

public void salva(Usuario usuario) { manager.getTransaction().begin(); if (usuario.getId() == 0) { manager.persist(usuario); } else { manager.merge(usuario); } manager.getTransaction().commit(); manager.close(); }

```
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Alterei o códido da minha classe modelo, para:

@NotNull
    @Temporal(TemporalType.DATE)
    @Column(name = "data_cadastro")
    private Date dataCadastro;

E no méto do DAO tentei:

    public void salva(Usuario usuario) {
        manager.getTransaction().begin();
        if (usuario.getId() == 0) {
            usuario.setDataCadastro(new Date(System.currentTimeMillis()));
            manager.persist(usuario);
        } else {
            manager.merge(usuario);
        }
        manager.getTransaction().commit();
        manager.close();
    }

Tentei também alterar o método para:

    public void salva(Usuario usuario) {
        manager.getTransaction().begin();
        if (usuario.getId() == 0) {
            manager.persist(usuario);
            usuario.setDataCadastro(new Date(System.currentTimeMillis()));
        } else {
            manager.merge(usuario);
        }
        manager.getTransaction().commit();
        manager.close();
    }

Mas em ambas tentativas não deu certo...

23 respostas

Ewerton boa tarde, o seu id não está auto increment? Dentro do if você esta colocando se o id do usuario é igual a 0. a vereficação seria essa mesma?

Boa tarde Alisson!

A verificação está correta SIM...

Pq se for 0, significa que é um NOVO registro, então eu chamo o persist, e faço uma INCLUSÃO no BD...

Se for diferente de 0 eu chamo o merge, para ATUALIZAR o registro no BD...

Ewerton o seu problema está na data? quando você atualiza uma instancia ele muda a data é isso?

Correto...

Eu que que....

Caso seja um novo cadastro, seja adicionado a data atual, OK, isso está fazendo...

Porém se o cadastro já estiver com a "data_cadastro" preenchida eu NÃO quero sobreescrever essa data...

Tente mudar algo para


    @Temporal(TemporalType.DATE)
    @Column
    private Calendar dataContratada = Calendar.getInstance();

public Calendar getDataContratada() {
        return dataContratada;
    }

    public void setDataContratada(Calendar dataContratada) {
        this.dataContratada = dataContratada;
    }

no seu view tenta algo assim, só para testar mesmo...

    <p:outputLabel value="Data Contratada" for="data" />
                    <p:calendar showOn="button" effect="fold"
                        value="#{funcionarioBean.funcionario.dataContratada.time}"
                        id="data">
                        <f:convertDateTime pattern="dd/MM/yyyy"
                            timeZone="America/Sao_Paulo" />
                    </p:calendar>

Ewerton a forma como você fez esta correta, podemos fazer de várias formas esse tipo de validação, uma delas seria verificar se é um novo registro ou não, exatamente como você fez no DAO.

O problema é o MySQL, ele que esta atualizando sua data, semana passada tive o mesmo problema com o meu blog, havia um campo timestamp e estava sendo atualizado sozinho, verificando e pesquisando em vários forums, até na documentação do MySQL, constatei que isso é um bug dele.

Para corrigir o problema você tem que retirar o not null da coluna do banco de dados, ai ele não vai atualizar a data sozinho.

Alisson eu estou usando .jsp e não .jsf

Obrigado!!

Matheus retirei a anotação @NotNull... Eclui o BD e recriei-o, mas não funcionou... Testei no Oracle e também ocorreu o msm problema...

Como esta seu modelo e dao ?

Modelo:

    @Temporal(TemporalType.DATE)
    @Column(name = "data_cadastro")
    private Date dataCadastro;

Dao:

    public void salva(Usuario usuario) {
        manager.getTransaction().begin();
        if (usuario.getId() == 0) {
            usuario.setDataCadastro(new Date(System.currentTimeMillis()));
            manager.persist(usuario);
        } else {
            manager.merge(usuario);
        }
        manager.getTransaction().commit();
        manager.close();
    }

Estranho, era para funcionar, no meu caso deu certo.

Tenta adicionar:

@Column(name = "data_cadastro", nullable = true)

Após criar o banco no MySQL, verifique como ficou a tabela:

desc TABLE_NAME;

Fiz, mas não deu certo Matheus... Eu havia comentado o campo dataCadastro no formulario.jsp, porque eu estava preenchendo automaticamente na casse modelo... Ai fiz a alteração no Dao, verificando de é um novo registro e atribuindo a data atual...

Primeiro descomentei o input, e verifiquei que a dataCadastro estava sendo carregada pelo método atualiza:

            <input type="date" name="usuario.dataCadastro" id="dataCadastro" class="form-control" value="${usuario.dataCadastro}"/><br />
            <ebf:validationMessage name="usuario.dataCadastro" />

Porém ao salvar o registo, perde a informação...

Faz o seguinte, vamos esquecer o java um pouco e ir para o MySQL.

Primeiro; Faça um insert manual na tabela, diretamente pelo console do MySQL ou alguma ferramenta que você usa para administrar os bancos.

Segundo: Faça um update também manual no MySQL do mesmo registro que realizou o insert, da mesma forma que o insert, verifique se a data irá ser atualizada.

Ok, vou fazer o seguinte Matheus... Pelo Workbenchi, vou cadastrar um usuário adicionando na dataCadastro a data de hj... Mudo a data do micro para 22, e atualizo algo no cadastro , mas não mexo na cadaCadastro...

OK ?? Pode ser assim...

Fiz o seguinte Matheus... Adicionei um usuário "na mão", sem peencher a dataCadastro... => Gravou normalmente

Alterei esse registro adicionando a data atual... => Gravou normalmente

Alterei novamente esse msm registro, apagando a dataCadastro... => Gerou ERRO...

Operation failed: There was an error while applying the SQL script to the database.
Executing:
UPDATE `ebfvaz`.`tweb_usuario` SET `data_cadastro`='' WHERE `id`='3';

ERROR 1292: 1292: Incorrect date value: '' for column 'data_cadastro' at row 1
SQL Statement:
UPDATE `ebfvaz`.`tweb_usuario` SET `data_cadastro`='' WHERE `id`='3'

OBS.: Pelo Workbench

Dei um "Desc" na tabela e o campo data_cadastro está como Null - Yes

Ewerton o teste que eu queria fazer era outro, faz assim:

Insere um novo usuario, na hora de informar a data passe a data atual

insert into tweb_usuario(campos..., data_cadastro) values (valores..., current_date);

Troque o campos.. pelos outros campos e valores... pelos valores, com isso irá gravar um novo registro com a data atual.

Feito isso, faça um select e veja a data que gravou:

select data_cadastro from tweb_usuario where id = ?

Feito isso, faça um update em qualquer campo menos na data:

update tweb_usuario set nome = 'OUTRO NOME' where id = ?

Ai você repete o select para verificar se o MySQL atualizou a data sozinho:

select data_cadastro from tweb_usuario where id = ?

Fiz Matheus, conforme vc orientou... Dei o insert, colocando "current_date", para dataCadstro, e null para dataLogin.... Dei o select e gravou a data atual - OK... Dei um update alterando o "nome", e a dataCadastro e dataLogin mantiveram os valores... 21/12/2016 e null, respectivamente...

solução!

Certo, então o problema realmente esta na aplicação pois o banco de dados não fez a atualização das datas.

Adicione um input hidden no seu formulário para manter o valor da data:

<input name="modelo.atributoData" type="hidden" value="<fmt:formatDate pattern="dd/MM/yyyy" type="date" value="${modelo.atributoData}"/>">

Troque modelo.atributoData de acordo com seu modelo e atributo referente a data, acredito que deva resolver, antes de persistir o objeto, o mesmo ja estará com a data definida.

Perfeito Matheus!!!

Muito obrigado de coração!!!

Que isso, sempre que precisar, só da um toque kkkk

Olá Mateus, essa solução resolve porque mantem o valor da data na requisição e ao submeter o form, a data vai preenchida, no entanto, visto que a data de criação não deve ser modificada "NUNCA" ,isso cai em um erro de segurança, pois algum espertinho pode ir lá com um firebug da vida e modificar o valor da data, quando o form for submetido a data vai alterada. Eu tenho uma aplicação que tem um caso parecido, quando eu salvo um registro, eu salvo o usuario que criou e a data da criação do registro e antes de atualizar eu faço assim:

@Put
public void editar(Registro registro){

Registro registroToUpdate = registroDao.find(registro.getRegistroId);

registro.toUpdate.setPropriedade(registro.getPropriedade());

registroToUpdate.setPropriedade2(registro.getPropriedade2());

registroDao.update(registroToUpdate);

}

Não sei se é o correto, mas dessa forma eu garanto que só serão atualizados os campos que realmente devem ser atualizados.

Qual a opinião de vocês?

Boa observação Ricardo, acredito que hoje eu antes de salvar buscaria o registro para pegar a data e passar antes do update ou criaria uma trigger no banco de dados, algo do tipo.

Talvez não sejam as melhores idéias, ou seja, tem N maneiras de resolver o problema.