Solucionado (ver solução)
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.