GRAVE: javax.faces.FacesException: Cannot create a session after the response has been committe

11 respostas
manolo

Pessoal,

minha aplicação de cadastro de contatos estava rodando normalmente, mas de repente ela não renderiza mais o DataGrid.

Abaixo está a pilha de erros:

2/11/2011 21:18:50 com.sun.faces.renderkit.RenderKitUtils renderHtmlErrorPage
AVISO: JSF1087: Não foi possível gerar a página de erro de Facelets porque a resposta  foi enviada.
02/11/2011 21:18:50 com.sun.faces.renderkit.RenderKitUtils renderHtmlErrorPage
GRAVE: javax.faces.FacesException: Cannot create a session after the response has been committed
javax.faces.FacesException: Cannot create a session after the response has been committed
	at com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:141)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119)
	at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:410)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:185)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:269)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed
	at org.apache.catalina.connector.Request.doGetSession(Request.java:2754)
	at org.apache.catalina.connector.Request.getSession(Request.java:2264)
	at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:899)
	at com.sun.faces.context.ExternalContextImpl.getSession(ExternalContextImpl.java:155)
	at com.sun.faces.renderkit.ServerSideStateHelper.writeState(ServerSideStateHelper.java:175)
	at com.sun.faces.renderkit.ResponseStateManagerImpl.writeState(ResponseStateManagerImpl.java:122)
	at com.sun.faces.application.StateManagerImpl.writeState(StateManagerImpl.java:166)
	at com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225)
	at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:418)
	at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	... 18 more

Aqui está o codigo:

Visão:
<?xml version='1.0' encoding='UTF-8' ?>
<!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:p="http://primefaces.prime.com.tr/ui"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <title>Cadastro de Clientes TCC Ciência da Computação</title>
    </h:head>
    <h:body>
        <h:graphicImage value="/imagens/unifil.gif" style="width: 250px; padding-bottom: 10px "></h:graphicImage>
        <h:form>
            <p:panel id="painel" header="Cadastrar Novo Contato" style="margin-right: 870px">
                <p:messages />
                <h:panelGrid columns="3" >

                    <h:outputText value="Nome:" />
                    <p:inputText id="nome" size="25" value="#{controleCliente.contato.nome}" required="true" requiredMessage="Campo Nome Obrigatório"></p:inputText>
                    <p:watermark for="nome" value="Insira um nome" />  

                    <h:outputText value="Endereço:" />
                    <p:inputText id="endereco" size="25" value="#{controleCliente.contato.endereco}" required="true" requiredMessage="Campo Endereco Obrigatório" ></p:inputText>
                    <p:watermark for="endereco" value="Insira um Endereço" />  

                    <h:outputText value="Tel Residencial:" />
                    <p:inputText id="telres" size="25" value="#{controleCliente.contato.telres}" required="true" requiredMessage="Campo Telefone Obrigatório"></p:inputText>
                    <p:watermark for="telres" value="8888-8888" />  

                    <h:outputText value="Tel Celular:" />
                    <p:inputText id="tecel" size="25" value="#{controleCliente.contato.telcel}" required="true" requiredMessage="Campo Celular Obrigatório"></p:inputText>
                    <p:watermark for="tecel" value="8888-8888" />  

                    <h:outputText value="E-mail:" />
                    <p:inputText id="email" size="25" value="#{controleCliente.contato.email}" required="true" requiredMessage="Campo E-mail Obrigatório"></p:inputText>
                    <p:watermark for="email" value="[email removido]" />  

                </h:panelGrid>

                <h:panelGrid columns="2">
                    <p:commandButton value="Gravar"  onclick="confirmation.show()" type="button" image="ui-icon-disk"></p:commandButton>
                    <p:commandButton value="Limpar" type="reset" image="ui-icon-trash"></p:commandButton>

                    <p:confirmDialog message="Tem certeza que deseja gravar o contato?"  
                                     showEffect="bounce" hideEffect="explode"  
                                     header="Confirmação de Gravação" severity="alert" widgetVar="confirmation">  

                        <p:commandButton value="Sim" update="messages, @form, tdcontato" oncomplete="confirmation.hide()"  
                                         actionListener="#{controleCliente.gravarFormulario}" image="ui-icon-check"
                                         onclick="PrimeFaces.cleanWatermarks();"/>  
                        <p:commandButton value="Não" onclick="confirmation.hide()" type="button" image="ui-icon-close"/>   

                    </p:confirmDialog>

                </h:panelGrid> 

            </p:panel>
        </h:form>

        <h:form>
            <h:panelGrid>
                <p:dataTable id="tdContato"  var="p" rows="10" emptyMessage="Não existem registros!" paginator="true" value="#{controleCliente.listar()}" >
                    <p:column>
                        <f:facet name="header">
                            <h:outputText value="Nome" />
                        </f:facet>
                        <h:outputText value="#{p.nome}"/>
                    </p:column>
                    <p:column>
                        <f:facet name="header">
                            <h:outputText value="Endereço" />
                        </f:facet>
                        <h:outputText value="#{p.endereco}"/>
                    </p:column>
                    <p:column>
                        <f:facet name="header">
                            <h:outputText value="Telefone Residencial" />
                        </f:facet>
                        <h:outputText value="#{p.telres}"/>
                    </p:column>
                    <p:column>
                        <f:facet name="header">
                            <h:outputText value="Telefone Celular" />
                        </f:facet>
                        <h:outputText value="#{p.telcel}"/>
                    </p:column>
                    <p:column>
                        <f:facet name="header">
                            <h:outputText value="E-mail" />
                        </f:facet>
                        <h:outputText value="#{p.email}"/>
                    </p:column>
                </p:dataTable>
            </h:panelGrid>
        </h:form> 

        <h:graphicImage value="/imagens/amazon.jpg" style="width: 160px; padding-top: 30px "></h:graphicImage>

    </h:body>
</html>

O DAO:

public class ContatoHelper {

    Session session = null;
    Transaction tx = null;
    Contato contato;

    public ContatoHelper() {
        this.session = HibernateUtil.getSessionFactory().openSession();
    }

    public void gravarContato(Contato contato) {

        try {

            tx = session.beginTransaction();
            session.save(contato);
            tx.commit();

        } catch (HibernateException ex) {
            ex.printStackTrace();

        } finally {
            session.close();
        }
    }

    public List listarContatos() {

        tx = session.beginTransaction();
        List lista = session.createQuery("from Contato").list();
        tx.commit();
        return lista;

    }
}

E finalmente o MangedBean:

@ManagedBean
@RequestScoped
public class ControleCliente {

    private Contato contato;
    //private DataModel data;

    public ControleCliente() {
        this.contato = new Contato();
    }

    public String init() {

        Contato contato = new Contato();

        return "index.xhtml";
    }

    public void gravarFormulario(ActionEvent actionEvent) {
        ContatoHelper grvcontato = new ContatoHelper();

        grvcontato.gravarContato(contato);

        contato = new Contato();

        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Obrigado Pela Colaboração!", "Erro, tente de novo!");

        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    public List listar() {

        List<Contato> lista = new ContatoHelper().listarContatos();
        return lista;
    }

    public Contato getContato() {

        return contato;
    }

    public void setContato(Contato contato) {
        this.contato = contato;
    }
}


O que será que está acontecendo?

Estava tudo certo e de repente não funciona mais.

Agradeço o apoio de todos vocês!

11 Respostas

Linkel

Olá.

Sei que já faz tempo, mas estou passando exatamente por esse problema nesse momento (PrimeFaces 3.0.M4)… Estava tudo funcionando direitinho e, como em um passe de mágica, agora a página xhtml não renderiza completamente mais, só até o menu. A mensagem de erro no console é exatamente essa aí.

O que fazer para resolver isso?

Obrigado.

manolo

Linkel,

se não me falha a memoria, eu mudei o escopo do meu bean para session!

Linkel

manolo:
Linkel,

se não me falha a memoria, eu mudei o escopo do meu bean para session!


Pois é, o problema é que mu escopo já é Session… Quando coloco o state_save para o “client”, páginas que não têm componentes primefaces renderizam normalmente, mas as que possuem componentes do PrimeFaces não (aliás, renderizam só o menu, que é o do PrimeFaces mesmo)…

Outra luz?

chico_bass

Opa, boa tarde,

pelo que vi a dúvida não é de hoje, estou com o mesmo problema, alguém encontrou a solução ?
no meu caso estou usando escopo “Page”, estamos usando Spring + JSF 2.0 + PrimeFaces 2.

Valeu!

Linkel

chico_bass:
Opa, boa tarde,

pelo que vi a dúvida não é de hoje, estou com o mesmo problema, alguém encontrou a solução ?
no meu caso estou usando escopo “Page”, estamos usando Spring + JSF 2.0 + PrimeFaces 2.

Valeu!


chico_bass, no meu caso resolvi modificando o endereço da taglib, já que o PrimeFaces 3 teve isso alterado. Está certo de que está utilizando a taglib da versão 2 (uri=“http://primefaces.prime.com.tr/ui”)?

Abraço!

chico_bass

Então, eu testei usar o escopo de session ao invés de page e funcionou mas ainda estou brigando para resolver um problema aqui que é o seguinte, quando renderizado o dataTable não traz registros (sendo que o model tem registros) daí se clico na página 2 por exemplo ele traz os registros. Eu preciso entregar esse projeto até sexta e só falta resolver isso, tá osso! se tiveres algum exemplo ou tutorial para indicar eu agradeço (estou seguindo o showcase do prime mas até agora não consegui resolver o problema). Obrigado Linkel

Linkel

chico_bass:
Então, eu testei usar o escopo de session ao invés de page e funcionou mas ainda estou brigando para resolver um problema aqui que é o seguinte, quando renderizado o dataTable não traz registros (sendo que o model tem registros) daí se clico na página 2 por exemplo ele traz os registros. Eu preciso entregar esse projeto até sexta e só falta resolver isso, tá osso! se tiveres algum exemplo ou tutorial para indicar eu agradeço (estou seguindo o showcase do prime mas até agora não consegui resolver o problema). Obrigado Linkel
Brother, isso parece ser proveniente daquela velha sopa de estados do ciclo de vida do JSF 2.0. Cola aqui seu código da dataTable e o método que ela chama para eu poder entender melhor o que pode estar acontecendo.

chico_bass

Linkel:
chico_bass:
Então, eu testei usar o escopo de session ao invés de page e funcionou mas ainda estou brigando para resolver um problema aqui que é o seguinte, quando renderizado o dataTable não traz registros (sendo que o model tem registros) daí se clico na página 2 por exemplo ele traz os registros. Eu preciso entregar esse projeto até sexta e só falta resolver isso, tá osso! se tiveres algum exemplo ou tutorial para indicar eu agradeço (estou seguindo o showcase do prime mas até agora não consegui resolver o problema). Obrigado Linkel
Brother, isso parece ser proveniente daquela velha sopa de estados do ciclo de vida do JSF 2.0. Cola aqui seu código da dataTable e o método que ela chama para eu poder entender melhor o que pode estar acontecendo.

Segue o código:

no xhtml:

<p:dataTable value="#{testeController.modelAtivos}" id="tabelaTreinamentos" emptyMessage="Nenhum registro encontrado" rowIndexVar="var"
		    paginator="true" paginatorPosition="both" firstPageLinkLabel="Primeira" previousPageLinkLabel="Anterior" nextPageLinkLabel="Proxima" lastPageLinkLabel="ultima"
                    rows="100" var="treinamento" width="100%" page="2" lazy="true" dynamic="true" >

                    <p:column style="text-align:center; width:5%;"
                                     headerText="Curso" filterBy="#{treinamento.codigo}"
				     filterMatchMode="contains" filterStyle="width: 40px">
			 <h:outputText value="#{treinamento.codigo}" />
                    </p:column>

                    <p:column style="text-align:center; width:5%;"
                                     headerText="Área" filterBy="#{treinamento.area.nome}"
                                     filterMatchMode="contains" filterStyle="width: 40px">
                         <h:outputText value="#{treinamento.area.nome}" />
                     </p:column>

No Controller:

@Controller("testeController")
@Scope("session")
public class TesteController implements Serializable {

	private static final long serialVersionUID = 8037764675358393627L;

	@Autowired
	private TreinamentoService treinamentoService;

	private Usuario usuarioLogado;
	private Treinamento treinamento;
	private LazyDataModel<Treinamento> modelAtivos;
	private List<Treinamento> listaAtivos = new ArrayList<Treinamento>();

	@PostConstruct
	public void init() {
		
		loadAtivos();
				
	}

	public void loadAtivos() {

		Treinamento t = new Treinamento();
		t.setSituacao(1);

		listaAtivos = treinamentoService.findByParam(t,
				new Order[] { Order.desc("dataCadastro") }, "area",
				"area.regional");

		this.modelAtivos = new LazyTreinamentoDataModel(listaAtivos);

	}

	public class LazyTreinamentoDataModel extends LazyDataModel<Treinamento> {

		private List<Treinamento> datasource;

		public LazyTreinamentoDataModel(List<Treinamento> datasource) {
			this.datasource = datasource;
		}

		@Override
		public List<Treinamento> load(int first, int pageSize,
				String sortField, boolean arg3, Map<String, String> filters) {
			List<Treinamento> data = new ArrayList<Treinamento>();

			// filter
			for (Treinamento treinamento : datasource) {
				boolean match = true;

				for (Iterator<String> it = filters.keySet().iterator(); it
						.hasNext();) {
					try {
						String filterProperty = it.next();
						String filterValue = filters.get(filterProperty);
						String fieldValue = String.valueOf(treinamento
								.getClass().getField(filterProperty)
								.get(treinamento));

						if (filterValue == null
								|| fieldValue.startsWith(filterValue)) {
							match = true;
						} else {
							match = false;
							break;
						}
					} catch (Exception e) {
						match = false;
					}
				}

				if (match) {
					data.add(treinamento);
				}
			}

			// rowCount
			int dataSize = data.size();
			this.setRowCount(dataSize);

			// paginate
			if (dataSize > pageSize) {
				try {
					return data.subList(first, first + pageSize);
				} catch (IndexOutOfBoundsException e) {
					return data.subList(first, first + (dataSize % pageSize));
				}
			} else {
				return data;
			}
		}

	};

	/*
	 * Getters and Setters
	 */

Então, fui pesquisando e encontrei um post no blog do cagatai civici http://cagataycivici.wordpress.com/2006/07/10/jsf_datatable_with_custom_paging/
enquanto isso vou dar uma olhada lá pra ver se identifico onde estou errando e já te agrradeço de antemão pela ajuda!

Valeu Linkel.

Linkel

Não sei dizer com certeza em que momento esse componente (dataTable) será renderizado dentre o ciclo de vida. Mas tenho quase certeza que seja antes do “postConstruct”, e como você só carrega seu model no postConstruct será impossível mesmo que o dataTable saiba que existem registros nele no final do ciclo. Tente mudar isso e me diga no que dá.

chico_bass

Como eu faria pra carregar o model antes do @PostConstruct ? Não faço idéia…

E

Coloquei isso no web.xml e parou…

<context-param>   
    <param-name>com.sun.faces.writeStateAtFormEnd</param-name>   
    <param-value>false</param-value>   
    </context-param>

Nas minhas pesquisas na net muitos diziam que era problema do glassfish testa ai vê se funciona…

Criado 2 de novembro de 2011
Ultima resposta 5 de out. de 2012
Respostas 11
Participantes 4