Lista perdendo valor em EJB

Boa tarde,

Estou criando uma lógica simples de carrinho de compras, mas estou com um problema que minha lista está simplesmente perdendo o valor após a adição de um ítem novo.

[code]
@Stateful
public class CarrinhoBean {

private final List<String> produtos = new ArrayList<String>();

public void adiciona(final String produto) {
    this.produtos.add(produto);
}

public void remove(final String produto) {
    this.produtos.remove(produto);
}

public final List<String> getProdutos() {
    return this.produtos;
    
}

public void listagem() {
    System.out.println(this.produtos);
}

}[/code]

[code]
@ManagedBean
public class CarrinhoMB {

@EJB
private CarrinhoBean carrinhoBean;

private String produto;

public List<String> getProdutos() {
    final List<String> lista = new ArrayList(this.carrinhoBean.getProdutos());
    return lista;
}

public void adiciona() {
    this.carrinhoBean.adiciona(this.produto);
    
}

public void remove(final String produto) {
    this.carrinhoBean.remove(produto);
}

public final String getProduto() {
    return produto;
}

public final void setProduto(final String produto) {
    this.produto = produto;
}

public void listagem() {
    this.carrinhoBean.listagem();
}

}[/code]

[code]

<h:head>
Carrinho de Compras
</h:head>

<h:body>
<h:form>
<h:outputLabel value=“Produto: " />
<h:inputText value=”#{carrinhoMB.produto}" />
<h:commandButton action="#{carrinhoMB.adiciona}"
value=“Adicionar ao Carrinho” />

	<hr />
	
	<h:outputLabel value="Listagem: " />
    <h:commandButton action="#{carrinhoMB.listagem}" value="Listagem" />

	<h:outputLabel value="Produtos no carrinho :" />
	<h:dataTable value="#{carrinhoMB.produtos}" var="p">
		<h:column>
			<h:outputText value="#{p}" />
		</h:column>
	</h:dataTable>

</h:form>

</h:body>[/code]

Quando chamo o método Listagem() (que so foi criado para tentar resolver o problema) minha lista está vazia. Agora se eu coloco um Sysout no método adicionar(), a lista é preenchida, mas saindo dele já esvazia.

Alguém saberia me ajudar?

Obrigado.

O stateful fica vivo enquanto a referência dele existir.

Vc está injetando esse cara em um ManagedBean request scoped, ao final de cada requisição esse cara morre e com isso morre tb a referência do ejb.

Mude o escopo do ManagedBean.

OBS.: É uma pessima prática injetar algo stateful em algum componente de escopo menor.

Muito obrigado pelo resposta. Eu trabalhando com SessionScoped a lista parou de perder os valores, apesar de meu JSF ainda não exibir os dados.

Quando disse ser uma má prática fazer o que esou fazendo, qual seria o ideal?

[quote=dambros]Muito obrigado pelo resposta. Eu trabalhando com SessionScoped a lista parou de perder os valores, apesar de meu JSF ainda não exibir os dados.

Quando disse ser uma má prática fazer o que esou fazendo, qual seria o ideal?[/quote]Na boa? Nunca vi um caso que justificasse utilizar Stateful. Então não sei te falar qual seria a melhor prática. [=

Como eu faria um exemplo de Carrinho de Compra não mantendo o estado então, se eu não usar Stateful?

[quote=dambros]Como eu faria um exemplo de Carrinho de Compra não mantendo o estado então, se eu não usar Stateful?[/quote]Pq não usar o HTTPSession? muito mais simples e fácil. É possível também utilizar cookie, ou uma solução mais radical seria persistir no DB.

Faz sentido. Como estou tentando aprender EJB e JSF, estou obrigando-me a utilizar essas tecnologias pra tudo ultimamente.

Você saberia me dizer porque meu método getProdutos() da classe CarrinhoBean retorna 13 outputs vazios se eu coloco um Sysout nele? A lista parece que tem valor após eu ter corrigido o scope, mas no método que deveria preencher meu JSF ela simplesmente está vazia.

[code]
@Stateful
public class CarrinhoBean {

private final  List<String> produtos = new ArrayList<String>();

public void adiciona(final String produto) {
    this.produtos.add(produto);
}

public void remove(final String produto) {
    this.produtos.remove(produto);
}

public final List<String> getProdutos() {
    System.out.println(this.produtos);
    return this.produtos;
    
}

public void listagem() {
    System.out.println(this.produtos);
}

}[/code]

Faz sentido. Como estou tentando aprender EJB e JSF, estou obrigando-me a utilizar essas tecnologias pra tudo ultimamente.

Você saberia me dizer porque meu método getProdutos() da classe CarrinhoBean retorna 13 outputs vazios se eu coloco um Sysout nele? A lista parece que tem valor após eu ter corrigido o scope, mas no método que deveria preencher meu JSF ela simplesmente está vazia.

[code]
@Stateful
public class CarrinhoBean {

private final  List<String> produtos = new ArrayList<String>();

public void adiciona(final String produto) {
    this.produtos.add(produto);
}

public void remove(final String produto) {
    this.produtos.remove(produto);
}

public final List<String> getProdutos() {
    System.out.println(this.produtos);
    return this.produtos;
    
}

public void listagem() {
    System.out.println(this.produtos);
}

}[/code][/quote]Desculpe, mas não sei.

Não analisei seu código. Apenas analisei o conceito aplicado. [=

Tu pode usar o @Stateless e usar o scopo de sessão…

Ali no teu metodo listagem, no System.out.pr… bota produtos.size() pra ti saber o tamanho dele.

A produtos só vão aparecer na tabela quando:

  1. Tu add produtos na lista.
  2. Tu atualizar a dataTable.
    Pra ti não perde muito tempo só dá um F5 na tela depois que tu add produtos.

Testa ai… qlqer coisa explico melhor.

Abraço!

[quote=diego_pereira]Tu pode usar o @Stateless e usar o scopo de sessão…

Ali no teu metodo listagem, no System.out.pr… bota produtos.size() pra ti saber o tamanho dele.

A produtos só vão aparecer na tabela quando:

  1. Tu add produtos na lista.
  2. Tu atualizar a dataTable.
    Pra ti não perde muito tempo só dá um F5 na tela depois que tu add produtos.

Testa ai… qlqer coisa explico melhor.

Abraço![/quote]

Primeiramente obrigado pelo retorno.

Tentei apertar F5 na página, mas mesmo assim o valor não é mostrado. O size() mostra corretamente (usando Stateful), mas o valor não atualiza no JSF.

Mantive igualmente como postei. Há algum erro nele?

Olá pessoal, dambros, eu não gosto muito de usar o xhtml como vc fez. Prefiro me preocupar apenas com o que vai dentro das tags <f:view></f:view>. Acho que as demais tags como head, body, não precisar vir de facelets. Qdo eu comecei a lidar com isso, alguns dos fields e tables realmente não apareciam. Aí, decidi fazer como fiz abaixo e não tive mais esse tipo de problema.

Se vc quiser, pode tentar usando assim:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
	  xmlns:f="http://java.sun.com/jsf/core" 
	  xmlns:h="http://java.sun.com/jsf/html">
	  
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Área Pública</title>
</head>
<body>
<f:view>
<!-- Coloque aqui seus facelets -->
</f:view>
</body>
</html>

No mais, tudo que vc fez eu fiz aqui pra testar e deu certo, com lista exibindo e tudo.

Tente tb dar um “clean” no projeto e no seu servidor de aplicação. Pode ser que tenha alguma sujeira atrapalhando tb, que é bastante comum…

[quote=Emerzoom]Olá pessoal, dambros, eu não gosto muito de usar o xhtml como vc fez. Prefiro me preocupar apenas com o que vai dentro das tags <f:view></f:view>. Acho que as demais tags como head, body, não precisar vir de facelets. Qdo eu comecei a lidar com isso, alguns dos fields e tables realmente não apareciam. Aí, decidi fazer como fiz abaixo e não tive mais esse tipo de problema.

Se vc quiser, pode tentar usando assim:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
	  xmlns:f="http://java.sun.com/jsf/core" 
	  xmlns:h="http://java.sun.com/jsf/html">
	  
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Área Pública</title>
</head>
<body>
<f:view>
<!-- Coloque aqui seus facelets -->
</f:view>
</body>
</html>

No mais, tudo que vc fez eu fiz aqui pra testar e deu certo, com lista exibindo e tudo.

Tente tb dar um “clean” no projeto e no seu servidor de aplicação. Pode ser que tenha alguma sujeira atrapalhando tb, que é bastante comum…[/quote]
chefe, blz?

valeu pela ajuda mas esse post tem um ano.

Dê uma lida no guia do GUJ que diz para não postar em posts velhos. [=

Até. [=

Ops!!! Wrong way!!

Mas fica a info se alguem quiser tentar. Nem me atentei a data, mas, blz.