Tratamento de Exception

Olá Comunidade.

Estou com um pequeno problema e gostaria de dividir com vcs, seguinte:

Eu tenho um form onde insiro dados para registrar uma enquete, ou seja, a pergunta e as alternativas a serem votadas. Até ai tudo bem, insiro a pergunta e a primeira alternativa, só que, se a alternativa que o usuário(que no meu caso caso é um gerente) não for a desejada e ele resolver remover, é ai que ocorre o problema.

eis o código da enquete_edit:

[code]
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:a=“http://richfaces.org/a4j"
xmlns:rich=“http://richfaces.org/rich"
template=”/layout/template.xhtml”>

<ui:define name="body">
	<h:form id="enquete" styleClass="edit">
		<rich:panel>
			<f:facet name="header">Cadastro de Enquete</f:facet>
			<s:decorate id="tituloField" template="/layout/edit.xhtml">
				<ui:define name="label">Titulo</ui:define>
				<h:inputText id="titulo" value="#{enquete.titulo}" style=" width : 339px;"/>
			</s:decorate>
			
			<s:decorate id="dataInicioField" template="/layout/edit.xhtml">
				<ui:define name="label">Data Inicial</ui:define>
				<rich:calendar id="dataInicio"
					value="#{enquete.dataInicio}" />
			</s:decorate>
			
			<s:decorate id="dataFimField" template="/layout/edit.xhtml">
				<ui:define name="label">Data Final</ui:define>
				<rich:calendar id="dataFim"
					value="#{enquete.dataFim}" />
			</s:decorate>
			
			
			<s:decorate id="itemField" template="/layout/edit.xhtml">
				<ui:define name="label">Alternativas</ui:define>
				<h:inputText id="item" value="#{enqueteManager.resposta}" />
				<h:commandButton action="#{enqueteManager.armazenarResposta}" value="Inserir" />
			</s:decorate>
			
			<s:decorate id="respostasField" template="/layout/edit.xhtml" rendered="#{enquete.respostas != null}">
				<h:dataTable id="resposta" value="#{enquete.respostas}" var="resposta">
					<h:column>
					<f:facet name="header">
						<h:outputText value="Resposta" />
					</f:facet>
					<h:outputText id="itensField" value="#{resposta.itens}"/>						
					</h:column>
					<h:column>
					<f:facet name="header"> 
							<h:outputText value="Acao" />
					</f:facet>	
					<h:commandButton id="remover" action="#{enqueteManager.removerResposta(resposta.itens)}" value="Remover"
						onchange="#{enqueteManager.resposta}"/>					
					</h:column>
				</h:dataTable>
			</s:decorate>
			
							
			<s:decorate id="statusField" template="/layout/edit.xhtml">
				<ui:define name="label">Status</ui:define>
				<h:selectOneListbox id="status"
					value="#{enquete.status}">
					<s:convertEnum />
					<s:enumItem enumValue="ATIVADO" label="Ativar" />
					<s:enumItem enumValue="DESATIVADO" label="Desativar" />
				</h:selectOneListbox>
				</s:decorate>
									
			<div style="clear: both"><span class="required">*</span>
			Campos obrigat&oacute;rios</div>
		</rich:panel>
		<div class="actionButtons"><h:commandButton id="save"
			value="Salvar" action="#{enqueteManager.salvarEnquete}" /> 
			<s:button id="cancelar" value="Cancelar" propagation="end" view="/home.xhtml"/>
		</div>
	</h:form>
</ui:define>

</ui:composition>[/code]

agora o código do meu Managed Bean:

[code]package br.ibict.bibliotecavirtual.session;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.annotations.datamodel.DataModelSelection;
import org.jboss.seam.faces.FacesMessages;

import br.ibict.bibliotecavirtual.entity.Enquete;
import br.ibict.bibliotecavirtual.entity.ItemEnquete;
import br.ibict.bibliotecavirtual.entity.Usuario;

@Name(“enqueteManager”)
@Scope(ScopeType.CONVERSATION)
public class EnqueteManager {

@DataModelSelection
@In(required=false)
@Out(required=false)
private Enquete enquete = new Enquete();
@DataModel
private List<Enquete> enquetes = new ArrayList<Enquete>();
@In
private EntityManager entityManager;
@In
private FacesMessages facesMessages;
@In
private Usuario usuarioLogado;

private String resposta;

private String respostaSelecionada = new String();




public String getResposta() {
	return resposta;
}
public void setResposta(String resposta) {
	this.resposta = resposta;
}
	

public String getRespostaSelecionada() {
	return respostaSelecionada;
}
public void setRespostaSelecionada(String respostaSelecionada) {
	this.respostaSelecionada = respostaSelecionada;
}
//=== Getter and Setters ====
@SuppressWarnings("unchecked")
@Factory(value="enquetes", autoCreate = true)
public List<Enquete> getEnquetes() {
	
	if(enquetes != null){
		
		enquetes = (List<Enquete>) entityManager.createQuery("Select e from Enquete e").getResultList();
	}
	return enquetes;
}
public void setEnquetes(List<Enquete> enquetes) {
	this.enquetes = enquetes;
}

//== fim dos getters and setters =====






@End
public String salvarEnquete(){
	//Se a chave primario for nula e usuario logado for um gerente, então
	if(enquete.getId() == null){
		System.out.println("Persistindo registros..."); //Mensagem a ser exibida no log do servidor
		enquete.setData(new Date()); //configura a data atual do sistema
		enquete.setGerentes(usuarioLogado); // Configura o gerente logado no sistema e armazena na lista
		entityManager.persist(enquete);//Grava os registros na table Enquete
		enquetes.add(enquete); //Adiciona os registros a uma lista
		facesMessages.add("Enquete salva com sucesso."); //Imprime mensagem na view Web 			
	}
	else{
		
		entityManager.merge(enquete); // Atualiza os registros na table Enquete
		facesMessages.add("Enquete salva com sucesso."); //Imprime mensagem na view Web
	}		
	return "salvarEnquete";
}//=== fim do método ====


@End
public String removerEnquete(){
	
		
		//Faz uma busca na table Enquete através da chave primário
		Enquete eqt = entityManager.find(Enquete.class, enquete.getId());
		//Se o objeto não for nulo, então
		if(eqt != null){
			
			entityManager.refresh(eqt);//Atualiza a base de dados
			entityManager.remove(eqt); //Remove o registros da table Enquete
			enquetes.remove(eqt); //Remove o registro da lista de Enquetes
			entityManager.flush(); //Sincroniza a base de dados
			facesMessages.add("Enquete removida com sucesso.");//Imprime mensagem na view Web
		
	}		
	return "removerEnquete";
}//==== fim do método =======

@Begin(join=true)
public String editarEnquete(){
	
	entityManager.refresh(enquete);//Edita os registros da enquete
	
	return "editarEnquete";
	
}//== fim do método =====

@Begin(join=true)
public String novaEnquete(){
	//Se o usuario logado for um gerente, então
	enquete = new Enquete(); //Insere uma nova enquete
	return "novaEnquete";
}

//Método para armazenar as alternativas da enquete
public void armazenarResposta(){
	
	ItemEnquete item = new ItemEnquete();
	item.setItens(resposta);
	if(enquete.getRespostas() == null){
		enquete.setRespostas(new ArrayList<ItemEnquete>());
	}
	enquete.getRespostas().add(item);
	
}


public void removerResposta(String resp){
	
	
	//Objeto recebe o argumento passado pelo parâmetro resposta.itens da view
	respostaSelecionada = resp;
	//Se resposta e respostaSelecionada não for nula	
	if(enquete.getRespostas() != null && respostaSelecionada != null){
		
		//Percorre os valores adicionados no ArrayList<ItemEnquete>
		for(ItemEnquete item: enquete.getRespostas()){
			
			//Se item for igual a resposta selecionada para exclusão, então
			if(item.getItens().equals(respostaSelecionada)){
				
				System.out.println("#Excluindo item da lista....");
				enquete.getRespostas().remove(item); //Remove resposta da lista antes de persistí-la
				System.out.println("#Exclusão feita com sucesso...." + item.getItens());
				System.out.println("###Retornando ao for");
				
			}
			else{
				System.out.println("##Retornando o indice da lista...");
				enquete.getRespostas().indexOf(item);
				//enquete.getRespostas().remove(respostaSelecionada);
				
			
			}
			
		}
	}
	//return "removerResposta";

}

}//=== fim da classe =====
[/code]

Sendo rápido na explicação, ele consegue remover o meu objeto da lista ItemEnquete, porém ele volta para o for(ItemEnquete item: enquete.getRespostas()), quando ocorre a seguinte exception:

16:21:55,812 ERROR [application] java.util.ConcurrentModificationException
javax.faces.el.EvaluationException: java.util.ConcurrentModificationException.

Alguém já pegou essa exception na carreira de desenvolvedor Java e se puder , como fez para solucionar esse problema?

Estive lendo a documentação e, isso ocorre pq tem um método interno na classe Interator que quando um objeto não tiver referência ou instância nenhuma dentro de uma lista ele manda essa excessão.

Ficarei grato se pudermos discutir sobre a solução para esse problema.

Um abraço comunidade.

Marcelo Soares

vc não pode remover um item de uma lista enquanto esta percorrendo pela mesma…

um conselho seria vc criar uma cópia dela para fazer a interação e depois remover os itens da lista original:


List original = new ArrayList() //essa aqui vc já tem.
List copia = new ArrayList(original)  //constroi uma cópia passando a original no construtor.

for(Object o:copia){
  orignal.remove(o) //aqui esta ok.
  copia.remove(o) //aqui vai dar exceção.
}

Valeu Giuliano

Vou tentar fazer isso e depois te mando um feedback. Um abraço

[quote=Giulliano]vc não pode remover um item de uma lista enquanto esta percorrendo pela mesma…

um conselho seria vc criar uma cópia dela para fazer a interação e depois remover os itens da lista original:


List original = new ArrayList() //essa aqui vc já tem.
List copia = new ArrayList(original)  //constroi uma cópia passando a original no construtor.

for(Object o:copia){
  orignal.remove(o) //aqui esta ok.
  copia.remove(o) //aqui vai dar exceção.
}

[/quote]

Vc pode remover enquanto itera,mas tem que usar o iterator explictiamente.


List original = new ArrayList() //essa aqui vc já tem.

for(Iterator it = original.iterator();it.hasNext();){
   //remove
   it.remove();
}