Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
14
respostas

Combatendo o Lazy (ou pelo menos tentanto)

Tenho uma classe cliente no meu sistema e essa classe se relaciona com outras 3 (Pedido, Telefone e Reclamaçã) - Código abaixo.

Gostaria que verificassem o código e me dissessem porque estou tendo problemas ao retirar o CascadeType. ALL e o Fetch EAGER das classes. O que tenho que mudar nos meus métodos de persistência.

CLASSE CLIENTE

public class Cliente implements Comparable<Cliente> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotEmpty(message = "Nome não pode estar em branco")
    private String nome;
    @Temporal(TemporalType.DATE)
    private Calendar dataCadastro = Calendar.getInstance();
    @Embedded
    private Endereco endereco;
    @OneToMany(mappedBy = "cliente", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    private List<Pedido> pedidos = new ArrayList<Pedido>();
    @OneToMany(mappedBy = "cliente", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @NotEmpty(message = "Pelo menos um telefone é necessário")
    private List<Telefone> telefones = new ArrayList<Telefone>();
    @OneToMany(mappedBy = "cliente", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    private List<Reclamacao> reclamacoes = new ArrayList<Reclamacao>();

Pedido

@Entity
public class Pedido implements Comparable<Pedido> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idPedido;
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar dataHoraPedido;
    private BigDecimal trocoPara = new BigDecimal(0);
    @Enumerated(EnumType.STRING)
    private FormaDePagamento formaDePagamento;
    @Enumerated(EnumType.STRING)
    private StatusPedido status = StatusPedido.EM_CRIACAO;
    private Boolean pago = false;
    private Boolean entregue = false;
    @ManyToOne(cascade = CascadeType.ALL)
    private Cliente cliente;
    @ManyToOne(cascade = CascadeType.ALL)
    private Movimento movimento;
    @OneToMany(mappedBy = "pedido", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER, orphanRemoval = true)
    private List<ItemPedido> itens = new ArrayList<ItemPedido>();

CLASSE TELEFONE

@Entity
@Cacheable
public class Telefone implements Comparable<Telefone> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long idTelefone;
    @Column(unique = true, length=12)
    @NotEmpty(message = "Número do telefone não pode estar em branco")
    private String numero = "";
    @Enumerated(EnumType.STRING)
    private TipoTelefone tipo = TipoTelefone.CELULAR;
    @ManyToOne(cascade = CascadeType.PERSIST)
    private Cliente cliente;

CLASSE RECLAMAÇÃO

@Entity
public class Reclamacao {
    @Id
    @GeneratedValue
    private Long id;
    private String txtReclamacao;
    private boolean visualizada;
    @ManyToOne(cascade = CascadeType.PERSIST)
    private Cliente cliente;
14 respostas

Correção do título: Tentando*

Qual erro acontece quando tira as opções Rafael ?

Ao consultar um cliente por seu telefone:

Error processing request
Context Path:
/Entregas

Servlet Path:
/atendente/pedido.xhtml

Path Info:
null

Query String:
null

Stack Trace
javax.servlet.ServletException: failed to lazily initialize a collection of role: info.rafaelmenezes.entregas.model.Cliente.telefones, could not initialize proxy - no Session
javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)
io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
solução!

Oi Rafael,

o seu problema é arquitetural, como vc lida com o EntityManager.

Quando vc retira o EAGER os relacionamentos não são carregados na hora, apenas quando vc acessa o relacionamento.

Ou seja, o JPA/Hibernate vai carregar a lista de telefones apenas quando vc tenta acessar:

List<Telefone> telefones = cliente.getTelefones();

Nesse momento o EntityManager já está fechado que impossibilita o carregamento da lista.

Duas possiveis soluçõse:

  • usa OpenEntityManagerInView que fecha o EM após renderização da view
  • usa uma Query planejada que vc executa o fetch do relacionamento através na query

A gente fala sobre isso nos cursos JPA e JPA2:

https://cursos.alura.com.br/course/jpa/section/6/exercise/10

https://cursos.alura.com.br/course/jpa-avancado/section/4

abs

Boa tarde, senhores. Nico, consultei minha apostila da Caelum (Curso FJ-25) e implementei (acredito eu) o OpenEntityManagerInView.

Segue o código

ClienteDao

package info.rafaelmenezes.entregas.persistence;

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

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import info.rafaelmenezes.entregas.model.Cliente;

@Stateless
public class ClienteDao implements Serializable {
    private static final long serialVersionUID = 1L;

    @Inject
    private EntityManager manager;

    public ClienteDao() {
    }

    public void adiciona(Cliente cliente) {
        this.manager.joinTransaction();
        this.manager.persist(cliente);
    }

    public void atualiza(Cliente cliente) {
        this.manager.joinTransaction();
        this.manager.merge(cliente);
    }

    public void remove(Cliente cliente) {
        this.manager.joinTransaction();
        this.manager.remove(cliente);
    }

    public Cliente busca(Long id) {
        this.manager.joinTransaction();
        return this.manager.find(Cliente.class, id);
    }

    public EntityManager getManager() {
        return manager;
    }

    public void setManager(EntityManager manager) {
        this.manager = manager;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    public List<Cliente> lista() {
        this.manager.joinTransaction();
        String jpql = "select c from Cliente c";
        TypedQuery<Cliente> query = this.manager.createQuery(jpql, Cliente.class);
        List<Cliente> lista = query.getResultList();
        System.out.println(lista);
        return lista;
    }

    public static void main(String[] args) {
        System.out.println(new ClienteDao().lista());
    }
}

EntityManagerProduces

package info.rafaelmenezes.entregas.util;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;

@ApplicationScoped
public class EntityManageProducer {

    @PersistenceUnit
    private EntityManagerFactory factory;

    @RequestScoped
    @Produces
    public EntityManager createAppEntityManager() {
        return factory.createEntityManager();
    }

    public void close(@Disposes EntityManager manager) {
        manager.close();
    }
}

ClienteBean

package info.rafaelmenezes.entregas.mb;

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

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.component.api.UIData;

import info.rafaelmenezes.entregas.model.Cliente;
import info.rafaelmenezes.entregas.model.Endereco;
import info.rafaelmenezes.entregas.model.Pedido;
import info.rafaelmenezes.entregas.model.Telefone;
import info.rafaelmenezes.entregas.persistence.ClienteDao;
import info.rafaelmenezes.entregas.util.Mensageiro;

@Named
@SessionScoped
public class ClienteBean implements Serializable {
    private static final long serialVersionUID = 1L;
    private Cliente cliente = new Cliente();
    private Endereco endereco = new Endereco();
    private List<Cliente> clientes = new ArrayList<Cliente>();
    private Cliente clienteExcluir;
    private UIData tabelaClientes;
    private ClienteDao clienteDao;
    private PedidoBean pedidoBean;
    private Mensageiro mensageiro = new Mensageiro();

    public ClienteBean() {
    }

    @Inject
    public ClienteBean(ClienteDao clienteDao, PedidoBean pedidoBean) {
        super();
        this.clienteDao = clienteDao;
        this.pedidoBean = pedidoBean;
    }

    @PostConstruct
    public void init() {
        this.cliente.setEndereco(this.endereco);
        Telefone t = new Telefone();
        this.cliente.getTelefones().add(t);
    }

    public Cliente getCliente() {
        return cliente;
    }

    public void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    public List<Cliente> getClientes() {
        this.clientes = clienteDao.lista();
        return this.clientes;
    }

    public void setClientes(List<Cliente> clientes) {
        this.clientes = clientes;
    }

    public Endereco getEndereco() {
        return endereco;
    }

    public void setEndereco(Endereco endereco) {
        this.endereco = endereco;
    }

    public Cliente getClienteExcluir() {
        return clienteExcluir;
    }

    public void setClienteExcluir(Cliente clienteExcluir) {
        this.clienteExcluir = clienteExcluir;
    }

    public UIData getTabelaClientes() {
        return tabelaClientes;
    }

    public void setTabelaClientes(UIData tabelaClientes) {
        this.tabelaClientes = tabelaClientes;
    }

    public String gravaCliente() {
        setaClienteNosTelefones();
        if (ehNovoCliente()) {
            this.cliente.setEndereco(this.endereco);
            this.clienteDao.adiciona(cliente);
            return novoPedido();
        } else {
            return atualizaCliente();
        }
    }

    public void setaClienteNosTelefones() {
        for (Telefone telefone : cliente.getTelefones()) {
            telefone.setCliente(cliente);
        }
    }

    public boolean ehNovoCliente() {
        return this.cliente.getId() == null;
    }

    public String novoPedido() {
        this.pedidoBean.abrePedido();
        this.clientes = clienteDao.lista();
        this.mensageiro.mostraInfo("Cliente gravado com sucesso");
        Pedido p = new Pedido();
        p.setCliente(cliente);
        this.pedidoBean.setPedido(p);
        this.limpaFormularioDoJSF();
        return "pedido?faces-redirect=true";
    }

    public String atualizaCliente() {
        this.cliente.setEndereco(this.endereco);
        this.clienteDao.atualiza(cliente);
        limpaFormularioDoJSF();
        this.clientes = clienteDao.lista();
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,
                "Cliente atualizado com sucesso", "Cliente atualizado com sucesso"));
        return "cliente";
    }

    public void botaClientePraEdicao(String id) {
        this.cliente = this.clienteDao.busca(new Long(id));
        this.endereco = cliente.getEndereco();
    }

    public String cancelaGravacao() {
        if (ehNovoCliente()) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Cancelou criação do cliente", "Cancelou criação do cliente"));
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Cancelou edição do cliente", "Cancelou edição do cliente"));
        }
        limpaFormularioDoJSF();
        return "cliente?faces-redirect=true";
    }

    public String limpaFormularioDoJSF() {
        this.cliente = new Cliente();
        this.clienteExcluir = new Cliente();
        this.endereco = new Endereco();
        this.cliente.setTelefones(new ArrayList<Telefone>());
        this.cliente.getTelefones().add(new Telefone());
        return "cliente?faces-redirect=true";
    }

    public String limpaNome() {
        this.cliente.setNome("");
        return "cliente";
    }

    public boolean formProntoPraGravar() {
        if (this.cliente.getNome() != "" && this.endereco.getLogradouro() != "" && this.endereco.getNumero() != ""
                && this.endereco.getBairro() != "") {
            return true;
        } else {
            return false;
        }
    }

}

Classe Cliente

package info.rafaelmenezes.entregas.model;

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

import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.validator.constraints.NotEmpty;

import info.rafaelmenezes.entregas.util.Formatador;

@Entity
public class Cliente implements Comparable<Cliente> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotEmpty(message = "Nome não pode estar em branco")
    private String nome;
    @Temporal(TemporalType.DATE)
    private Calendar dataCadastro = Calendar.getInstance();
    @Embedded
    private Endereco endereco;
    @OneToMany
    private List<Pedido> pedidos = new ArrayList<Pedido>();
    @OneToMany
    @NotEmpty(message = "Pelo menos um telefone é necessário")
    private List<Telefone> telefones = new ArrayList<Telefone>();
    @OneToMany
    private List<Reclamacao> reclamacoes = new ArrayList<Reclamacao>();

    public Cliente() {
        // TODO Auto-generated constructor stub
    }

    public Long getId() {
        return id;
    }

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

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public Calendar getDataCadastro() {
        return dataCadastro;
    }

    public void setDataCadastro(Calendar dataCadastro) {
        this.dataCadastro = dataCadastro;
    }

    public String getDataCadastroString() {
        return Formatador.dataAmigavel(this.dataCadastro);
    }

    public Endereco getEndereco() {
        return endereco;
    }

    public void setEndereco(Endereco endereco) {
        this.endereco = endereco;
    }

    public List<Telefone> getTelefones() {
        return telefones;
    }

    public void setTelefones(List<Telefone> telefones) {
        this.telefones = telefones;
    }

    public List<Pedido> getPedidos() {
        return pedidos;
    }

    public void setPedidos(List<Pedido> pedidos) {
        this.pedidos = pedidos;
    }

    public List<Reclamacao> getReclamacoes() {
        return reclamacoes;
    }

    public void setReclamacoes(List<Reclamacao> reclamacoes) {
        this.reclamacoes = reclamacoes;
    }

    public void adicionaTelefone(Telefone t) {
        if (!this.telefones.contains(t)) {
            this.telefones.add(t);
        }
    }

    @Override
    public int compareTo(Cliente c) {
        return this.getId().compareTo(c.getId());
    }

    @Override
    public boolean equals(Object c) {
        Cliente c1 = (Cliente) c;
        return this.id.equals(c1.getId());
    }

    @Override
    public String toString() {
        return "Cliente [id=" + id + ", nome=" + nome + ", dataCadastro=" + dataCadastro.getTimeInMillis() + ", endereco=" + endereco
                + ", telefones=" + telefones + ", reclamacoes=" + reclamacoes + "]";
    }




}

Oi Rafael,

tem como adicionar um syso nos métodos do producer para acompanhar a abertura e fechamento do EntityManager? É importante descobrir se o método close é chamado antes ou depois da fase RENDER_VIEW do JSF.

abs

Preciso também implementar um PhaseListener pra logar as fases?

seria legal para acompanhar as fases!

abs

17:06:38,466 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 10.0.0.Final (WildFly Core 2.0.10.Final) started in 16349ms - Started 589 of 864 services (440 services are lazy, passive or on-demand)
17:06:40,340 INFO  [stdout] (default task-2) Entrando em : RESTORE_VIEW 1

17:06:40,397 INFO  [stdout] (default task-2) Saindo de : RESTORE_VIEW 1

17:06:40,401 INFO  [stdout] (default task-2) Entrando em : RENDER_RESPONSE 6

17:06:40,956 INFO  [stdout] (default task-2) ABRINDO UM EM

17:06:41,033 INFO  [org.hibernate.hql.internal.QueryTranslatorFactoryInitiator] (default task-2) HHH000397: Using ASTQueryTranslatorFactory
17:06:41,142 INFO  [stdout] (default task-2) Hibernate: 
17:06:41,142 INFO  [stdout] (default task-2)     select
17:06:41,142 INFO  [stdout] (default task-2)         cliente0_.id as id1_0_,
17:06:41,143 INFO  [stdout] (default task-2)         cliente0_.dataCadastro as dataCada2_0_,
17:06:41,143 INFO  [stdout] (default task-2)         cliente0_.bairro as bairro3_0_,
17:06:41,143 INFO  [stdout] (default task-2)         cliente0_.cep as cep4_0_,
17:06:41,144 INFO  [stdout] (default task-2)         cliente0_.complemento as compleme5_0_,
17:06:41,144 INFO  [stdout] (default task-2)         cliente0_.logradouro as logradou6_0_,
17:06:41,144 INFO  [stdout] (default task-2)         cliente0_.numero as numero7_0_,
17:06:41,144 INFO  [stdout] (default task-2)         cliente0_.nome as nome8_0_ 
17:06:41,145 INFO  [stdout] (default task-2)     from
17:06:41,145 INFO  [stdout] (default task-2)         Cliente cliente0_

17:06:41,206 INFO  [stdout] (default task-2) Hibernate: 
17:06:41,206 INFO  [stdout] (default task-2)     select
17:06:41,207 INFO  [stdout] (default task-2)         telefones0_.Cliente_id as Cliente_1_3_0_,
17:06:41,207 INFO  [stdout] (default task-2)         telefones0_.telefones_idTelefone as telefone2_3_0_,
17:06:41,207 INFO  [stdout] (default task-2)         telefone1_.idTelefone as idTelefo1_12_1_,
17:06:41,207 INFO  [stdout] (default task-2)         telefone1_.cliente_id as cliente_4_12_1_,
17:06:41,207 INFO  [stdout] (default task-2)         telefone1_.numero as numero2_12_1_,
17:06:41,207 INFO  [stdout] (default task-2)         telefone1_.tipo as tipo3_12_1_,
17:06:41,207 INFO  [stdout] (default task-2)         cliente2_.id as id1_0_2_,
17:06:41,207 INFO  [stdout] (default task-2)         cliente2_.dataCadastro as dataCada2_0_2_,
17:06:41,207 INFO  [stdout] (default task-2)         cliente2_.bairro as bairro3_0_2_,
17:06:41,207 INFO  [stdout] (default task-2)         cliente2_.cep as cep4_0_2_,
17:06:41,207 INFO  [stdout] (default task-2)         cliente2_.complemento as compleme5_0_2_,
17:06:41,207 INFO  [stdout] (default task-2)         cliente2_.logradouro as logradou6_0_2_,
17:06:41,208 INFO  [stdout] (default task-2)         cliente2_.numero as numero7_0_2_,
17:06:41,208 INFO  [stdout] (default task-2)         cliente2_.nome as nome8_0_2_ 
17:06:41,208 INFO  [stdout] (default task-2)     from
17:06:41,208 INFO  [stdout] (default task-2)         Cliente_Telefone telefones0_ 
17:06:41,208 INFO  [stdout] (default task-2)     inner join
17:06:41,208 INFO  [stdout] (default task-2)         Telefone telefone1_ 
17:06:41,208 INFO  [stdout] (default task-2)             on telefones0_.telefones_idTelefone=telefone1_.idTelefone 
17:06:41,208 INFO  [stdout] (default task-2)     left outer join
17:06:41,208 INFO  [stdout] (default task-2)         Cliente cliente2_ 
17:06:41,208 INFO  [stdout] (default task-2)             on telefone1_.cliente_id=cliente2_.id 
17:06:41,208 INFO  [stdout] (default task-2)     where
17:06:41,209 INFO  [stdout] (default task-2)         telefones0_.Cliente_id=?

17:06:41,218 INFO  [stdout] (default task-2) Hibernate: 
17:06:41,218 INFO  [stdout] (default task-2)     select
17:06:41,218 INFO  [stdout] (default task-2)         reclamacoe0_.Cliente_id as Cliente_1_2_0_,
17:06:41,218 INFO  [stdout] (default task-2)         reclamacoe0_.reclamacoes_id as reclamac2_2_0_,
17:06:41,218 INFO  [stdout] (default task-2)         reclamacao1_.id as id1_10_1_,
17:06:41,218 INFO  [stdout] (default task-2)         reclamacao1_.cliente_id as cliente_4_10_1_,
17:06:41,218 INFO  [stdout] (default task-2)         reclamacao1_.txtReclamacao as txtRecla2_10_1_,
17:06:41,218 INFO  [stdout] (default task-2)         reclamacao1_.visualizada as visualiz3_10_1_,
17:06:41,219 INFO  [stdout] (default task-2)         cliente2_.id as id1_0_2_,
17:06:41,219 INFO  [stdout] (default task-2)         cliente2_.dataCadastro as dataCada2_0_2_,
17:06:41,219 INFO  [stdout] (default task-2)         cliente2_.bairro as bairro3_0_2_,
17:06:41,219 INFO  [stdout] (default task-2)         cliente2_.cep as cep4_0_2_,
17:06:41,219 INFO  [stdout] (default task-2)         cliente2_.complemento as compleme5_0_2_,
17:06:41,219 INFO  [stdout] (default task-2)         cliente2_.logradouro as logradou6_0_2_,
17:06:41,219 INFO  [stdout] (default task-2)         cliente2_.numero as numero7_0_2_,
17:06:41,219 INFO  [stdout] (default task-2)         cliente2_.nome as nome8_0_2_ 
17:06:41,219 INFO  [stdout] (default task-2)     from
17:06:41,219 INFO  [stdout] (default task-2)         Cliente_Reclamacao reclamacoe0_ 
17:06:41,219 INFO  [stdout] (default task-2)     inner join
17:06:41,219 INFO  [stdout] (default task-2)         Reclamacao reclamacao1_ 
17:06:41,219 INFO  [stdout] (default task-2)             on reclamacoe0_.reclamacoes_id=reclamacao1_.id 
17:06:41,220 INFO  [stdout] (default task-2)     left outer join
17:06:41,220 INFO  [stdout] (default task-2)         Cliente cliente2_ 
17:06:41,220 INFO  [stdout] (default task-2)             on reclamacao1_.cliente_id=cliente2_.id 
17:06:41,220 INFO  [stdout] (default task-2)     where
17:06:41,220 INFO  [stdout] (default task-2)         reclamacoe0_.Cliente_id=?

17:06:41,223 INFO  [stdout] (default task-2) Hibernate: 
17:06:41,223 INFO  [stdout] (default task-2)     select
17:06:41,223 INFO  [stdout] (default task-2)         telefones0_.Cliente_id as Cliente_1_3_0_,
17:06:41,224 INFO  [stdout] (default task-2)         telefones0_.telefones_idTelefone as telefone2_3_0_,
17:06:41,224 INFO  [stdout] (default task-2)         telefone1_.idTelefone as idTelefo1_12_1_,
17:06:41,224 INFO  [stdout] (default task-2)         telefone1_.cliente_id as cliente_4_12_1_,
17:06:41,224 INFO  [stdout] (default task-2)         telefone1_.numero as numero2_12_1_,
17:06:41,224 INFO  [stdout] (default task-2)         telefone1_.tipo as tipo3_12_1_,
17:06:41,224 INFO  [stdout] (default task-2)         cliente2_.id as id1_0_2_,
17:06:41,224 INFO  [stdout] (default task-2)         cliente2_.dataCadastro as dataCada2_0_2_,
17:06:41,224 INFO  [stdout] (default task-2)         cliente2_.bairro as bairro3_0_2_,
17:06:41,225 INFO  [stdout] (default task-2)         cliente2_.cep as cep4_0_2_,
17:06:41,225 INFO  [stdout] (default task-2)         cliente2_.complemento as compleme5_0_2_,
17:06:41,225 INFO  [stdout] (default task-2)         cliente2_.logradouro as logradou6_0_2_,
17:06:41,225 INFO  [stdout] (default task-2)         cliente2_.numero as numero7_0_2_,
17:06:41,225 INFO  [stdout] (default task-2)         cliente2_.nome as nome8_0_2_ 
17:06:41,225 INFO  [stdout] (default task-2)     from
17:06:41,225 INFO  [stdout] (default task-2)         Cliente_Telefone telefones0_ 
17:06:41,225 INFO  [stdout] (default task-2)     inner join
17:06:41,226 INFO  [stdout] (default task-2)         Telefone telefone1_ 
17:06:41,226 INFO  [stdout] (default task-2)             on telefones0_.telefones_idTelefone=telefone1_.idTelefone 
17:06:41,226 INFO  [stdout] (default task-2)     left outer join
17:06:41,226 INFO  [stdout] (default task-2)         Cliente cliente2_ 
17:06:41,226 INFO  [stdout] (default task-2)             on telefone1_.cliente_id=cliente2_.id 
17:06:41,226 INFO  [stdout] (default task-2)     where
17:06:41,226 INFO  [stdout] (default task-2)         telefones0_.Cliente_id=?

17:06:41,229 INFO  [stdout] (default task-2) Hibernate: 
17:06:41,229 INFO  [stdout] (default task-2)     select
17:06:41,229 INFO  [stdout] (default task-2)         reclamacoe0_.Cliente_id as Cliente_1_2_0_,
17:06:41,229 INFO  [stdout] (default task-2)         reclamacoe0_.reclamacoes_id as reclamac2_2_0_,
17:06:41,229 INFO  [stdout] (default task-2)         reclamacao1_.id as id1_10_1_,
17:06:41,229 INFO  [stdout] (default task-2)         reclamacao1_.cliente_id as cliente_4_10_1_,
17:06:41,229 INFO  [stdout] (default task-2)         reclamacao1_.txtReclamacao as txtRecla2_10_1_,
17:06:41,230 INFO  [stdout] (default task-2)         reclamacao1_.visualizada as visualiz3_10_1_,
17:06:41,230 INFO  [stdout] (default task-2)         cliente2_.id as id1_0_2_,
17:06:41,230 INFO  [stdout] (default task-2)         cliente2_.dataCadastro as dataCada2_0_2_,
17:06:41,230 INFO  [stdout] (default task-2)         cliente2_.bairro as bairro3_0_2_,
17:06:41,230 INFO  [stdout] (default task-2)         cliente2_.cep as cep4_0_2_,
17:06:41,230 INFO  [stdout] (default task-2)         cliente2_.complemento as compleme5_0_2_,
17:06:41,230 INFO  [stdout] (default task-2)         cliente2_.logradouro as logradou6_0_2_,
17:06:41,230 INFO  [stdout] (default task-2)         cliente2_.numero as numero7_0_2_,
17:06:41,230 INFO  [stdout] (default task-2)         cliente2_.nome as nome8_0_2_ 
17:06:41,230 INFO  [stdout] (default task-2)     from
17:06:41,231 INFO  [stdout] (default task-2)         Cliente_Reclamacao reclamacoe0_ 
17:06:41,231 INFO  [stdout] (default task-2)     inner join
17:06:41,231 INFO  [stdout] (default task-2)         Reclamacao reclamacao1_ 
17:06:41,231 INFO  [stdout] (default task-2)             on reclamacoe0_.reclamacoes_id=reclamacao1_.id 
17:06:41,231 INFO  [stdout] (default task-2)     left outer join
17:06:41,231 INFO  [stdout] (default task-2)         Cliente cliente2_ 
17:06:41,231 INFO  [stdout] (default task-2)             on reclamacao1_.cliente_id=cliente2_.id 
17:06:41,231 INFO  [stdout] (default task-2)     where
17:06:41,232 INFO  [stdout] (default task-2)         reclamacoe0_.Cliente_id=?

17:06:41,235 INFO  [stdout] (default task-2) Retorno do método lista em clienteDao: [Cliente [id=1, nome=Rafael, dataCadastro=1457233200000, endereco=Rua Aladim, 88 - Bloco 1 Apto 302 - Valqueire, telefones=[], reclamacoes=[]], Cliente [id=2, nome=Juliao, dataCadastro=1458183600000, endereco=Colina Longa, 1 - Teste - Vila Militar, telefones=[], reclamacoes=[]]]

17:06:41,273 INFO  [stdout] (default task-2) Saindo de : RENDER_RESPONSE 6

17:06:41,275 INFO  [stdout] (default task-2) FECHANDO UM EM

Método lista no DAO


    public List<Cliente> lista() {
        this.manager.joinTransaction();
        String jpql = "select c from Cliente c";
        TypedQuery<Cliente> query = this.manager.createQuery(jpql, Cliente.class);
        List<Cliente> lista = query.getResultList();
        System.out.println("Retorno do método lista em clienteDao: " + lista);
        return lista;
    }

oi Rafael,

analisando o seu log, o EM está sendo fechando corretamente após a fase RENDER_RESPONSE. Na minha opinião não deve acontecer essa exceção :(

nessa mesma requisição acontece o problema?

abs

Nico, resolvido.

Como eu estava usando o fetchType.EAGER e o nosso amigo Matheus, sempre solicito, recomendou que eu tirasse ele, acabei tirando também o mappedBy sem perceber.

Acertando o mapeamento tudo funcionou. Agora irei utilizar a mesma técnica no restante do sistema.

Desculpa pelo erro besta!

Obrigado!

Mas valeu o aprendizado!

Rafael nenhum erro é besta pois são eles que nos fazem crescer e amadurecer, o importante é que o erro foi solucionado.