Tratamento de Exception

3 respostas
S

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:

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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>

agora o código do meu Managed Bean:

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 =====

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

3 Respostas

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.
}
S

Valeu Giuliano

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

sergiotaborda

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.
}

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();
}
Criado 22 de setembro de 2009
Ultima resposta 23 de set. de 2009
Respostas 3
Participantes 3