JSF - h:dataTable não lê dados do banco quando alterados manualmente

Eu estava fazendo alguns testes aqui e editei alguns campos da minha tabela diretamente no banco. Só que essas alterações simplesmente não reflete no dataTable.
Outra curiosidade:
Excluindo alguma linha, quando atualizo a página que contém o dataTable, atualiza o número de registros, mas não os campos alterados anteriormente.

Alguma idéia porque isso ocorre?

Posta o teu código para a galera ver

Vc deve dar commit no banco de dados para as alterações efetuadas.
Tente fazer isso, se não o fez.

cmonteiro,

Os dados estão lá commitados… Se fizer um select pelo banco os dados estão lá ok.
Fazendo um redeploy da minha aplicação aí ele le. O problema está quando eu abro o pgAdmin (por exemplo) e edito e em seguida dou o refresh na tela web…

Daniel,
Segue os códigos:

pacotes.xhtml

 <h:dataTable id="lista_pacotes" value="#{pacoteMB.lstPacotes}" var="pacote" class="table table-hover table-nomargin">
	    	<h:column>
	    		<f:facet name="header">Nome do pacote</f:facet>
	    		#{pacote.nome}
	    	</h:column>
	    	<h:column>
	    		<f:facet name="header">Preço</f:facet>
	    		<h:outputText value="#{pacote.preco}">
	    			<f:convertNumber pattern="#,###,##0.00" locale="pt_BR" ></f:convertNumber>
	    		</h:outputText> 
	    	</h:column>
	    	<h:column>
	    		<f:facet name="header"></f:facet>
	    		<h:commandLink class="bt_excluir" value="Excluir" onclick="return window.confirm('Deseja realmente excluir?')">
	    			<f:ajax render="@form" execute="lista_pacotes" event="click"/>
	    		</h:commandLink>
	    	</h:column>
	    </h:dataTable>

PacoteMB.java


@ManagedBean
public class PacoteMB {
	
	@EJB
	PacotesFacadeRemote pacoteFacade;
	
	private Pacotes pacote;
	private List<Pacotes> lstPacotes;
	
/*	@PostConstruct
	public void init(){
		pacote = new Pacotes();
		lstPacotes = pacoteFacade.listaAll();
	}*/
	
	public List<Pacotes> getLstPacotes() {
		//if(lstPacotes == null){
			
		//}
		return pacoteFacade.listaAll();
	}


	public Pacotes getPacote(){
		return this.pacote;
	}
	
	
	public String salvar(){
		pacoteFacade.save(pacote);
		return "pacote_novo";
	}
}

PacotesFacade.java

@Stateless
@LocalBean
public class PacotesFacade implements PacotesFacadeRemote {

   @EJB
   PacotesDAO pacotesDAO;
   
   public List<Pacotes> listaAll(){
	   return pacotesDAO.findAll();
   }

   public Pacotes save(Pacotes pacote){
	   return pacotesDAO.save(pacote);
   }
   
   public void delete(Pacotes pacote){
	   pacotesDAO.delete(pacote);
   }
}

PacotesDAO.java

@Stateless
@LocalBean
public class PacotesDAO extends GenericDAO<Pacotes> {

    public PacotesDAO() {
        super(Pacotes.class);
    }

    
    public Pacotes save(Pacotes pacote){
    	if(pacote.getIdPacote() != null){
    		return super.update(pacote);
    	}else{
    		super.insert(pacote);
    		return pacote;
    	}
    }
    
    public void delete(Pacotes pacote){
    	super.delete(pacote.getIdPacote(), Pacotes.class);
    }
    
    public List<Pacotes> findAll(){
    	System.out.println("findall");
    	return super.findAll();
    }
}

GenericDAO.java


public abstract class GenericDAO<T> {
	private final static String UNIT_NAME = "ProjetoEJB";

	
	@PersistenceContext(unitName = UNIT_NAME)
	private EntityManager em;

	private Class<T> entityClass;

	public GenericDAO(Class<T> entityClass) {
		this.entityClass = entityClass;
	}

	public void insert(T entity) {
		em.persist(entity);
	}

	protected void delete(Object id, Class<T> classe) {
		T entityToBeRemoved = em.getReference(classe, id);

		em.remove(entityToBeRemoved);
	}

	public T update(T entity) {
		return em.merge(entity);
	}

	public T find(int entityID) {
		return em.find(entityClass, entityID);
	}

	// Using the unchecked because JPA does not have a
	// em.getCriteriaBuilder().createQuery()<T> method
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<T> findAll() {
		CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
		cq.select(cq.from(entityClass));
		return em.createQuery(cq).getResultList();
	}

	// Using the unchecked because JPA does not have a
	// ery.getSingleResult()<T> method
	@SuppressWarnings("unchecked")
	protected T findOneResult(String namedQuery, Map<String, Object> parameters) {
		T result = null;

		try {
			Query query = em.createNamedQuery(namedQuery);

			// Method that will populate parameters if they are passed not null and empty
			if (parameters != null && !parameters.isEmpty()) {
				populateQueryParameters(query, parameters);
			}

			result = (T) query.getSingleResult();

		} catch (Exception e) {
			System.out.println("Error while running query: " + e.getMessage());
			e.printStackTrace();
		}

		return result;
	}

	private void populateQueryParameters(Query query, Map<String, Object> parameters) {

		for (Entry<String, Object> entry : parameters.entrySet()) {
			query.setParameter(entry.getKey(), entry.getValue());
		}
	}
}

Pacotes.java

@Entity
@NamedQuery(name="Pacote.findAll", query="SELECT p FROM Pacotes p")
public class Pacotes implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@SequenceGenerator(name="PACOTES_IDPACOTE_GENERATOR", sequenceName="pacotes_idpacote_seq", allocationSize=1)
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="PACOTES_IDPACOTE_GENERATOR")
	private Integer IdPacote;

	private String Descricao;

	private String Nome;

	private double preco;
	
	private int IdDestino;

	

	
	public Pacotes() {
	}

	public Integer getIdPacote() {
		return this.IdPacote;
	}

	public void setIdPacote(Integer IdPacote) {
		this.IdPacote = IdPacote;
	}

	public String getDescricao() {
		return this.Descricao;
	}

	public void setDescricao(String Descricao) {
		this.Descricao = Descricao;
	}

	public String getNome() {
		return this.Nome;
	}

	public void setNome(String Nome) {
		this.Nome = Nome;
	}

	public double getPreco() {
		return this.preco;
	}

	public void setPreco(double preco) {
		this.preco = preco;
	}

	public int getIdDestino() {
		return IdDestino;
	}

	public void setIdDestino(int idDestino) {
		IdDestino = idDestino;
	}

	
	@Override
	public int hashCode(){
		return getIdPacote();
	}
	
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Pacotes){
			Pacotes pac = (Pacotes)obj;
			return pac.getIdPacote() == getIdPacote();
		}
		return false;
	}

}

Mais alguns testes…

Abri a aplicação em dois browsers diferentes. O interessante é que se edito e salvo o registro em um browser e dou o refresh na lista em outro browser, ele lê normal; reconhece a alteração.
Então, tudo indica que o servidor jee faz algum tipo de cache, e como o servidor faz o gerenciamento dos objetos da aplicação, quando você edita pelo aplicativo mesmo, o servidor jee faz o devido update na lista de objetos e disponibiliza.

Outro ponto interessante: Deixei a aplicação “parada” algumas horas ontem quando fui almoçar. Quando dei refresh na tela, aí buscou os dados corretos do banco.

Mas ainda fica a dúvida: proque que não reconhece quando faço uma alteração direto do banco? Exisitiria alguma configuração do JPA que força a leitura do banco?
Minha preocupação é ter que fazer algum update direto no banco (em caso de atualização de versão do sistema, por exemplo) e isso não ser refletido para o cliente. E para isso, sempre que dar redeploy para tal.

Olá,
Qual foi a solução? Obrigado.
Att,
Mauricio Locatelli