Dados alteram no banco, mas não no Datatable depois de reload na página

10 respostas
P

Olá pessoal, gostaria de saber se alguém já passou por isso…

Tenho um datatable que traz os dados da tabela Usuário no banco… tenho um commandlink “Alterar” que quando clicado, abre um dialog com um formulário com os campos para poder alterar os dados do usuário, e depois de confirmado, o sistema volta pra tela mostrando o datatable com os dados já atualizado.

Pois bem, essa ação funciona perfeitamente… depois de confirmado, o dialog fecha e mostra o datatable atualizado. Porém se dou um reload na página, ou vou para outra página e volto nela, ele me mostra o datatable com os dados antigos (mas no banco de dados está OK - alterado). Se eu reiniciar o servidor, dai sim ele mostra os dados corretos…
Não sei o que fazer para corrigir isso… se alguém puder me dar uma luz…

.xhtml

<h:form id="form">
	<p:growl life="5000" autoUpdate="true" />
	<div class="titulo">BUSCA DE USUÁRIOS</div>
        	<p:dataTable emptyMessage="Nenhum usuário encontrado" value="#{usuarioBean.lista}" var="user" paginator="true" rows="10" style="text-align: center">
			<p:column style="width: 100px">
				<p:commandLink action="#{usuarioBean.setSelecionado(user)}" process="@this" update=":form:grid" title="Alterar" onclick="dlg_alterar.show()">
					<h:graphicImage value="/resources/images/edit.png" />
				</p:commandLink>
			</p:column>
			<p:column headerText="Nome" filterBy="#{user.nome}" filterMatchMode="contains">
				#{user.nome}
			</p:column>
			<p:column headerText="CPF" filterBy="#{user.cpf}" filterMatchMode="contains">
				#{user.cpf}
			</p:column>
			<p:column headerText="Telefone (1)" filterBy="#{user.fone1}" filterMatchMode="contains">
				#{user.fone1}
			</p:column>
		</p:dataTable>

		<p:dialog header="Alterar dados Cadastrais" resizable="false" modal="true" id="altuser" widgetVar="dlg_alterar">
			<h:panelGrid id="grid" columns="2" cellpadding="5" style="text-align: right">                  
                        //FORMULÁRIO..
				<p:commandButton value="Alterar" action="#{usuarioBean.salvar()}" update="@form" title="Alterar" icon="ui-icon-check"/>
			</h:panelGrid>
		</p:dialog>
	</div>
</h:form>

bean

@ManagedBean
@ViewScoped
public class UsuarioBean implements Serializable{

	private static final long serialVersionUID = -8236707856924581733L;

	@ManagedProperty(value="#{entityManagerBuilder.entityManager}")
	private EntityManager entityManager;

	private Usuario selecionado;
	private List<Usuario> lista;
	
	public void salvar() {

		FacesContext context = FacesContext.getCurrentInstance();
		try {
			getEntityManager().getTransaction().begin();
			
			if (getSelecionado().getCod_usuario() == null) {
				getEntityManager().persist(selecionado);
				context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Cadastrado realizado com Sucesso!", ""));
			}else{
				getEntityManager().merge(selecionado);
				context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Cadastrado alterado com Sucesso!", ""));
				
				listar_usuario();
			}
			getEntityManager().getTransaction().commit();
			
			selecionado = null;
		
		} catch (Exception e) {
		}
		
	}

	public void listar_usuario(){
		Query query = getEntityManager().createQuery("from Usuario");
		lista = query.getResultList();		
	}
	
	//GETTERS E SETTERS
	public Usuario getSelecionado() {
		if(selecionado == null){
			selecionado = new Usuario();
		}
		return selecionado;
	}

	public void setSelecionado(Usuario selecionado) {
		this.selecionado = selecionado;
	}

	public List<Usuario> getLista() {
		if(lista == null){
			listar_usuario();
		}
		return lista;
	}

Agradeço desde já!!

10 Respostas

juniormaverick

Boa noite pcsantana, acho que o problema é o seguinte, quando você faz o reload a lista já está inicializada, assim o método getLista verifica que a lista não é nula e não realiza a pesquisa dos novos registros.

Tenta mudar algo nesta direção ai, e depois nos informe abraços.

P

Obrigado pela resposta juniormaverick…

mas olhe no metodo salvar, quando faço uma alteração eu chamo o método listar_usuario();

}else{  
   getEntityManager().merge(selecionado);  
   context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Cadastrado alterado com Sucesso!", ""));  
             
   listar_usuario();  
}

dessa maneira meio que obrigo ele a executar a query… ou estou enganado?

se caso a lista nao é nula quando faço o reload, ele não deveria continuar com a lista adquirida no metodo anterior ( salvar() )??

Obrigado!

juniormaverick

Sim você está correto em relação a este trecho. Mas repare que você pesquisa antes de dar um getEntityManager().getTransaction().commit() no objeto alterado.

Estou dando um chute mas pode ser que isto tenha algo a haver e se perca.

Faz o seguinte posta o código da entidade, que faz um exemplo aqui e tento de ajudar.

Abraços.

P

Obrigado pela ajuda :smiley:

então, não sei se entendi bem certo o que quis dizer, e o que me pediu para postar… mas vou por aqui

Entidade Usuário

@Entity
@Table(name="usuario")
public class Usuario implements Serializable{

	private static final long serialVersionUID = -9046997852186220932L;

	@Id
	@SequenceGenerator(name="user", sequenceName="usuario_cod_usuario_seq",allocationSize=1)
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="user")
	@Column(name="cod_usuario", unique=true, nullable=false)
	private Integer cod_usuario;
	
	@NotEmpty(message="Preencha o campo Nome de Usuário")
	@Column(name="username", unique=true, nullable=false, length=15)
	private String username;
	
	@NotEmpty(message="Preencha o campo Nome Completo")
	@Column(name="nome", nullable=false, length=50)
	private String nome;
	
	@Column(name="senha", length=15)
	private String senha;
	
	@Column(name="endereco", length=200)
	private String endereco;
	
	@Column(name="numero")
	private Integer numero;
	
	@Column(name="complemento", length=40)
	private String complemento;
	
	@Column(name="bairro", length=50)
	private String bairro;

	@Column(name="cidade", length=50, columnDefinition = "default", insertable = false, updatable = true)
	private String cidade;
	
	@Column(name="uf", length=2, columnDefinition = "default", insertable = false, updatable = true)
	private String uf;
	
	@NotEmpty(message="Preencha o campo CPF")
	@Column(name="cpf", length=15, unique=true, nullable=false)
	private String cpf;
	
	@NotEmpty(message="Preencha o campo RG")
	@Column(name="rg", length=10)
	private String rg;
	
	@Column(name="fone2", length=15)
	private String fone2;
	
	@NotEmpty(message="Preencha o campo Telefone 1")
	@Column(name="fone1", length=15, nullable=false)
	private String fone1;
	
	@NotEmpty(message="Escolha o Tipo de Usuário")
	@Column(name="tipo_usuario", length=15, nullable=false)
	private String tipo_usuario;
	
	@Column(name="cep", length=9, columnDefinition = "default", insertable = false, updatable = true)
	private String cep;
		
	//GETTERS E SETTERS

Entity DAO

@ManagedBean(eager=true)
@ApplicationScoped
public class EntityManagerBuilder {
	
	private EntityManager entityManager;

	public EntityManager getEntityManager() {
		if(entityManager == null){
			createEntityManager();
		}
		return entityManager;
	}	
	private void createEntityManager(){
		EntityManagerFactory factory = Persistence.createEntityManagerFactory("sico");
		entityManager = factory.createEntityManager();
	}
}

Interessante é que eu fiz um método excluir, e esse funcionou… ele exclui o registro, e mostra a tabela atualizada sem o registro excluído mesmo dando f5 na página…

mas enfim, se puder me ajudar… Muito grato desde já!

Abraços

E

troque isso

public List<Usuario> getLista() { if(lista == null){ listar_usuario(); } return lista; }

por isso

public List<Usuario> getLista() { listar_usuario(); return lista; }

outra coisa tente usar o debug, que vc mata facinho isso aew
falow

P

Obrigado pela dica eduJava :smiley:

tinha chegado a tentar já isso ae depois que o junior comentou que talvez o método getLista verifica que a lista não é nula e não realiza a pesquisa dos novos registros… mas o problema continua…

vou tentando aqui, qualquer novidade eu posto aqui… se alguem tiver mais alguma sugestão (:

o que eu acho estranho é que ele chega a atualizar a lista e o datatable com os dados alterados… mas se der um atualizar na página volta… :s

P

Amigos, depois de tentando algumas coisas, aparentemente resolvi um problema e encontrei outro hehehe
troquei isso do UsuarioBean

@ManagedProperty(value="#{entityManagerBuilder.entityManager}")  
private EntityManager entityManager;

por isso, que é minha classe DAO

private EntityManagerBuilder entity;

Agora o metodo salvar fico assim

public void salvar() {

		FacesContext context = FacesContext.getCurrentInstance();
		try {			
			getEntity().getEntityManager().getTransaction().begin();
			
			if (getSelecionado().getCod_usuario() == null) {
				getEntity().getEntityManager().persist(selecionado);
				context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Cadastro realizado com Sucesso!", ""));
				
			}else{
				getEntity().getEntityManager().merge(selecionado);
				context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Cadastro alterado com Sucesso!", ""));						
			}
			getEntity().getEntityManager().getTransaction().commit();
			
			selecionado = null;
			listar_usuario();
			
		} catch (Exception e) {
		}
	}

fazendo isso, aparentemente resolveu o problema de eu atualizar a página e voltar com os dados antigos… porém agora, o action #{usuarioBean.setSelecionado(user)} do meu botao editar no datatable não funciona depois que é feito o comando alterar, e dado um atualizar na página… ele simplemente não seta os dados pro form para poder alterar…

alguma sugestao?

Obrigado!

P

fiz uns testes aqui, e na verdade não está nem entrando no método setSelecionado… e não precisa fazer uma alteração antes não! Só iniciar o servidor, dar um reload na páginaa, que o commandlink para setSelecionado já nao funciona…

juniormaverick

Boa noite PCSANTANA, faz o seguinte em seu commandlink utilize a tag do “f:setPropertyActionListener”, assim você não terá a necessidade de capturar a referência do objeto selecionado utilizando o action. Veja um exemplo de como ficaria.

<f:setPropertyActionListener target="#{usuarioBean.selecionado}" value="#{user}" />

Acredito que isto ajude a resolver o seu problema.

Abraços.

P

Obrigado Junior pela dica!
ficaria assim correto?

<p:commandLink process="@this" update=":form:grid" title="Alterar" onclick="dlg_alterar.show()">
	<f:setPropertyActionListener target="#{usuarioBean.selecionado}" value="#{user}" />
	<h:graphicImage value="/resources/images/edit.png" />
</p:commandLink>

funciona, mas só ate eu atualizar a página…
realmente ta dificil descobrir o que ta causando isso… =/

Criado 5 de agosto de 2012
Ultima resposta 7 de ago. de 2012
Respostas 10
Participantes 3