Dúvida Exemplo Livro Programação Java para Web

Bom dia

Estou fazendo um exemplo desse livro bem simples um cadastro utilizando jsf 2.0, hibernate e primefaces.

Utilizando os exemplo do livro criei um cadastro de usuario utilizando ajax e com scope do controller request esse exemplo possui dois formularios um de edição e outro de listagem os dois na mesma pagina, no exemplo o que me deixou em duvida eh o metodo public List getUsuarios() esse eh o metodo que alimenta minha datatable, no livro eh falado que por questão de desempenho e verificado nesse metodo se a lista esta nula, caso esteja faz a consulta no banco, caso esteja preenchida retorna ela sem fazer a consulta no banco, Dessa forma sempre no metodo salvar e remover no final setamos a lista com null.

Percebi que como estou utilzando o scope Request, essa lista sempre será nula, assim a cada requisição sempre irá buscar no banco novamente, mesmo que a chamada seja feito em ajax, percebi isso no link alterar da datatable, segue exemplo abaixo para análise

XHTML

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:p="http://primefaces.prime.com.tr/ui" template="/template.xhtml">

	<ui:define name="corpo">
		<h:form id="edicao">
			<p:messages />
			<h:inputHidden value="#{usuarioController.usuario.id}" />

			<h:panelGrid columns="2">

				<h:outputLabel value="Login:" for="login" />
				<h:inputText id="login" value="#{usuarioController.usuario.login}" maxlength="13" />

				<h:outputLabel value="Nome:" for="nome" />
				<h:inputText id="nome" value="#{usuarioController.usuario.nome}"
					maxlength="60" />

				<h:outputLabel value="Senha:" for="senha" />
				<h:inputSecret id="senha" redisplay="true" 
				    value="#{usuarioController.usuario.senha}" maxlength="8" />

				<h:outputLabel value="Confirmar Senha:" for="confirmaSenha" />
				<h:inputSecret id="confirmaSenha" redisplay="true"
					value="#{usuarioController.confirmaSenha}" maxlength="8"
					validator="#{usuarioController.validaConfirmaSenha}" />

				<h:outputText value="Tipo Usuário:" for="tipoUsuario" />
				<h:selectOneMenu id="tipoUsuario"
					value="#{usuarioController.usuario.tipoUsuario}">
					<f:selectItems value="#{usuarioController.tipoUsuario}" />
				</h:selectOneMenu>

				<h:outputText value="Ativo" for="status" />
				<h:selectBooleanCheckbox id="status"
					value="#{usuarioController.usuario.status}" />

			</h:panelGrid>

			<h:commandButton value="Salvar" action="#{usuarioController.salvar}">
				<f:ajax execute="@form" render=":edicao :listagem" />
			</h:commandButton>

		</h:form>

		<h:form id="listagem">
			<p:dataTable var="usuario" value="#{usuarioController.usuarios}"
				rows="10" scrollable="true" liveScroll="true" height="300"
				rendered="#{not empty usuarioController.usuarios}">

				<p:column headerText="Login">
					<h:outputText value="#{usuario.login}" />
				</p:column>

				<p:column headerText="Nome">
					<h:outputText value="#{usuario.nome}" />
				</p:column>

				<p:column headerText="Tipo Usuário">
					<h:outputText value="#{usuario.tipoUsuario}" />
				</p:column>
				
				<p:column headerText="Alterar">
				  <h:commandLink value="Alterar">
				    <f:ajax execute="@this" render=":edicao" />
				    <f:setPropertyActionListener target="#{usuarioController.usuario}" value="#{usuario}"></f:setPropertyActionListener>
				    <f:setPropertyActionListener target="#{usuarioController.confirmaSenha}" value="#{usuario.senha}"></f:setPropertyActionListener>  
				  </h:commandLink>
				</p:column>


				<p:column headerText="Remover">
				  <h:commandLink action="#{usuarioController.remover}" value="remover">
				    <f:ajax execute="@this" render=":listagem"/>
				    <f:setPropertyActionListener target="#{usuarioController.usuario}" value="#{usuario}"></f:setPropertyActionListener>
				  </h:commandLink>
				</p:column>

			</p:dataTable>

		</h:form>
	</ui:define>
</ui:composition>

Controller

@Scope("request")
@Controller("usuarioController")
public class UsuarioController {

	private Usuario usuario = new Usuario();
	private String confirmaSenha = "";
	private List<Usuario> usuarios = null;
	
	public void salvar() {
		FacesContext context = FacesContext.getCurrentInstance();
		String mensagem = "";
		
		try {
		  if (this.usuario.getId() == 0) {
			  mensagem = "Usuário: " + this.usuario.getLogin() + " inserido com sucesso!";
		      this.usuario = this.usuario.merge();
				this.usuario = new Usuario();
				this.usuarios = null;
		  } else {
			    mensagem = "Usuário: " + this.usuario.getLogin() + " alterado com sucesso!";
				Usuario usuarioAux = Usuario.findUsuario(this.usuario.getId());
				BeanUtils.copyProperties(this.usuario,usuarioAux);
				this.usuario = usuarioAux.merge();	  
				this.usuario = new Usuario();
				this.usuarios = null;
				
		  }
		  context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, mensagem, null));
		} catch (Exception ex) {
		  context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro ao tentar salvar o usuário!", ex.getMessage()));
		  ex.printStackTrace();
		}
	}

	public void remover() {

		FacesContext context = FacesContext.getCurrentInstance();
		String login = this.usuario.getLogin();
		try {
			this.usuario.remove();
			context.addMessage(null, new FacesMessage(
					FacesMessage.SEVERITY_INFO, "Usuário: " + login
							+ " removido com sucesso!", null));
			this.usuario = new Usuario();
			this.usuarios = null;
		} catch (Exception e) {
			context.addMessage(null, new FacesMessage(
					FacesMessage.SEVERITY_ERROR, "Erro ao tentat remover o usuário: "
							+ login+"!", e.getMessage()));
			e.printStackTrace();
		}
	}

	public List<Usuario> getUsuarios() {
		if (this.usuarios == null) {
			System.out.println("Entra aqui toda vez...");
			this.usuarios = Usuario.findAllUsuarios();
		}
		return this.usuarios;
	}

	public List<SelectItem> getTipoUsuario() {
		List<SelectItem> tipoUsuarioList = new LinkedList<SelectItem>();
		for (EnumTipoUsuario item : EnumTipoUsuario.values()) {
			tipoUsuarioList.add(new SelectItem(item));
		}
		return tipoUsuarioList;
	}
	
	// VALIDATOR VERIFICA SENHA
	public void validaConfirmaSenha(FacesContext context,
			UIComponent component, Object value) throws ValidatorException {
		List<UIComponent> children = component.getParent().getChildren();
		for (UIComponent child : children) {
			if (child.getId().equals("senha")) {
				UIInput input = (UIInput) child;
				String senha = (String) input.getValue();
				String confirmaSenha = (String) value;
				if (!confirmaSenha.equals(senha)) {
					throw new ValidatorException(new FacesMessage(
							"Confirmação de senha não confere!"));
				}
			}
		}
	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public String getConfirmaSenha() {
		return confirmaSenha;
	}

	public void setConfirmaSenha(String confirmaSenha) {
		this.confirmaSenha = confirmaSenha;
	}

}

Queria saber se estou pensando certo, principalmente no link alterar do datatable que ao clicar nele esta fazendo a consulta no banco novamente sem necessidade

at

Cara … tb tenho esse problema e ainda não consegui resolver essa questão …
Me fala uma coisa, que livro é esse que esta lendo ??
Abraços

Programação Java para a Web da Novatec

Itens do Livro: JavaServer Faces, Hibernate, Facelets, Segurança(Spring Security), Gráficos, Relatórios e WebServices

O Livro é bem legal com exemplo praticos.

abraços

Oi, não é necessário fazer uma nova consulta, pois o seu objeto ja está sendo persistido, o certo seria apenas pegar o objeto que ira ser editado e leva e colocar na mesma pagina de cadastro… para mais duvidas vou estar fazendo um exemplo com um crud… ou se preferir da uma estudada em <f:setPropertyActionListener /> pois ele pega o item selesionado e você pode fazer ações com ele… espero ter ajudado :);