Solucionado (ver solução)
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.