Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

org.hibernate.LazyInitializationException + JSF

Boa tarde,

Prezados(as) tenho duas classes no meu DAO que estão dando problemas, uma de livros que é a principal e outra de comentarios, elas possuem um relacionamento que é de um livro para muitos comentarios, mas quando vou utilizar meu metodo Bean de avaliação sou abordado com org.hibernate.LazyInitializationException.

Segue abaixo a classe do pacote modelo Livro:

package br.com.caelum.livraria.modelo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class Livro implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;

    private String titulo;
    private String isbn;
    private double preco;
    @Temporal(TemporalType.DATE)
    private Calendar dataLancamento = Calendar.getInstance();
    private Integer avaliacao;

    public Integer getAvaliacao() {

        return avaliacao;
    }

    public void setAvaliacao(Integer avaliacao) {
        this.avaliacao = avaliacao;
    }

    @ManyToMany(fetch = FetchType.EAGER)
    private List<Autor> autores = new ArrayList<Autor>();

    @OneToMany
    private List<Comentario> comentarios = new ArrayList<Comentario>();

    public List<Comentario> getComentarios() {
        return comentarios;
    }

    public List<Autor> getAutores() {
        return autores;
    }

    public void adicionaAutor(Autor autor) {
        this.autores.add(autor);
    }

    public void adicionaComentario(Comentario comentario) {
        this.comentarios.add(comentario);
    }

    public Livro() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public double getPreco() {
        return preco;
    }

    public void setPreco(double preco) {
        this.preco = preco;
    }

    public Calendar getDataLancamento() {
        return dataLancamento;
    }

    public void setDataLancamento(Calendar dataLancamento) {
        this.dataLancamento = dataLancamento;
    }

    public void removeAutor(Autor autor) {
        this.autores.remove(autor);
    }

}
5 respostas

Abaixo meu metodo de avaliação:

package br.com.caelum.livraria.bean;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import br.com.caelum.livraria.dao.DAO;
import br.com.caelum.livraria.modelo.Comentario;
import br.com.caelum.livraria.modelo.Livro;

@ManagedBean
@SessionScoped
public class RatingView {

    private Integer rating3;

    private Livro livro = new Livro();
    private Comentario comentario = new Comentario();



    public Comentario getComentario() {
        return this.comentario;
    }

    public void setComentario(Comentario comentario) {
        this.comentario = comentario;
    }

    public Livro getLivro() {
        return livro;
    }

    public void setLivro(Livro livro) {
        this.livro = livro;
    }

    /*
     * Recebe o objeto de livroBean e deixa disponivel para uso
     */
    public void recebeObjeto() {

        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext()
                .getRequest();
        HttpSession session = (HttpSession) request.getSession();
        this.livro = (Livro) session.getAttribute("livroId");

    }

    public String gravarAvaliacao() {
        System.out.println("Gravando livro " + this.livro.getTitulo());

        // O metodo abaixo verifica se o livro possui um autor, caso não possua ele não
        // permite a gravação



        DAO<Livro> dao = new DAO<Livro>(Livro.class);
        this.livro.adicionaComentario(comentario);
        System.out.println("Este é o comentario inserido: " + this.comentario);

        // Ao clicar no metodo gravar está condição é ativada, caso o livro já exista
        // ele é atualizado, caso contrario ele é atualizadoasd
        if (this.livro.getId() == null) {
            dao.adiciona(this.livro);
            this.livro.adicionaComentario(comentario);

        } else {
            dao.atualiza(this.livro);
        }

        return "livro?faces-redirect=true";
    }

    /*
     * O metodo retorna null para assim que a pagina for carregada as estrelas estão
     * em branco
     */
    public Integer getRating3() {
        return null;
    }

    /*
     * Se o livro nunca foi avaliado ou seja se a avaliacao for nula entao é
     * atribuido o valor de estrelas atual se o valor não for nulo soma o valor
     * atual com o novo
     */
    public void setRating3(Integer rating3) {

        if (this.livro.getAvaliacao() == null) {
            this.livro.setAvaliacao(rating3);
        } else {
            Integer temp = this.livro.getAvaliacao() + rating3;
            this.livro.setAvaliacao(temp);

        }

    }

}
set 17, 2017 1:04:09 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
ADVERTÊNCIA: #{ratingView.gravarAvaliacao}: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
javax.faces.FacesException: #{ratingView.gravarAvaliacao}: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
    at javax.faces.component.UICommand.broadcast(UICommand.java:315)
    at javax.faces.component.UIData.broadcast(UIData.java:1108)

Olá Clinton,

Tente atribuir o comportamento de EAGER para os comentários do Livro também.

Me parece que quando o JSF começa processar a tela para gerar a resposta para o usuário ele tenta buscar novamente pela lista de comentários do Livro, pois esta tem comportamento LAZY por padrão. Porém neste momento, já não há mais sessão ativa com o Hibernate.

Boa noite,

Cassio funciona mas olha que estranho.

@ManyToMany(fetch = FetchType.EAGER)
    private List<Autor> autores = new ArrayList<Autor>();

    @OneToMany(fetch = FetchType.EAGER)
    private List<Comentario> comentarios = new ArrayList<Comentario>();

Quando deixo a classe assim este é o erro que eu recebo:

set 18, 2017 6:31:55 PM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
GRAVE: javax.faces.application.ViewExpiredException: viewId:/login.xhtml - A exibição de /login.xhtml não pôde ser restaurada.
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:212)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:123)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

E quando eu deixo somente um EAGER funciona perfeitamente mas preciso dos dois, já viu algo assim ?

    @ManyToMany
    private List<Autor> autores = new ArrayList<Autor>();

    @OneToMany(fetch = FetchType.EAGER)
    private List<Comentario> comentarios = new ArrayList<Comentario>();
solução!

Eu mesmo encontrei a solução do meu Post kkkk

Eu não posso carregar duas listas na mesma classe então eu carreguei uma sub lista na minha classe comentarios

@ManyToMany(fetch = FetchType.EAGER) private List autores = new ArrayList();

@OneToMany(fetch = FetchType.EAGER) @Fetch(FetchMode.SUBSELECT) private List comentarios = new ArrayList(); ```