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

RESTEASY002025: Unknown exception while executing GET /livros/lancamentos/:

O serviço só funciona a primeira vez, quando chamo a segunda vez, acontece erro de Lazy, msmo tendo colocado como join fetch na query

package br.com.alura.loja.resources;

import java.util.List;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import br.com.alura.loja.dao.LivroDao;
import br.com.alura.loja.models.Livro;

@Path("/livros")
public class LivroResource {

    @Inject
    private LivroDao dao;

    @GET
    @Path("/lancamentos")
    @Produces({MediaType.APPLICATION_JSON})
    public List<Livro> ultimosLancamentosJson() {
        return dao.ultimosLancamentos();
    }

}
public class LivroDao {

    @PersistenceContext
    private EntityManager manager;

    public void salva(Livro livro) {
        manager.persist(livro);
    }


    public List<Livro> ultimosLancamentos() {
        String jpql = "select distinct(l) from Livro l join fetch l.autores order by l.dataPublicacao desc";
        return manager.createQuery(jpql, Livro.class).setMaxResults(5).setHint(QueryHints.HINT_CACHEABLE, true).getResultList(); //SetHint Vai cachear a busca

    }
5 respostas
11:53:21,725 ERROR [org.jboss.resteasy.resteasy_jaxrs.i18n] (default task-1) RESTEASY002025: Unknown exception while executing GET /livros/lancamentos/: com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: br.com.alura.loja.models.Livro.autores, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->br.com.alura.loja.models.Livro["autores"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:391)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351)
    at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:727)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:145)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:400)
    at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1392)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:913)
    at org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider.writeTo(ResteasyJackson2Provider.java:240)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:137)
    at org.jboss.resteasy.core.interception.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:61)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:124)
    at org.jboss.resteasy.security.doseta.DigitalSigningInterceptor.aroundWriteTo(DigitalSigningInterceptor.java:146)
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:129)
    at org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$2(ServerResponseWriter.java:140)
    at org.jboss.resteasy.core.interception.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:395)
    at org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:207)
    at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:85)
    at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:59)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:530)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:461)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:231)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:137)
    at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:361)
    at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:140)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:217)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)

Oi Thiago, tudo bem?

O problema é o FetchType.LAZY da classe Livro. Quando o Jackson converte a Entidade Livro ele tenta carregar os autores, mas a sessão do hibernate está fechada e essa exception é lançada.

Tente incluir o seguinte código no seu projeto:

@Configuration
public class CustomWebMvcAutoConfig extends WebMvcConfigurerAdapter{
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (@SuppressWarnings("rawtypes") HttpMessageConverter converter : converters) {
            if (converter instanceof org.springframework.http.converter.json.MappingJackson2HttpMessageConverter) {
                ObjectMapper mapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
                mapper.registerModule(new Hibernate4Module());
                // replace Hibernate4Module() with the proper class for your hibernate version.
            }
        }
    }
}

Poste aqui seu pom.xml e a classe Livro também :)

Abraço!

Olá Otavio,

Olhando depois o codigo disponibilizado pelo instrutor do curso, ele transformou a classe LivroDao em EJB utilizando o @Statefull e @PersistenceContext(type = PersistenceContextType.EXTENDED). O uso do Join fetch não ja resolveria a questao de carregar os livros e os autores na mesma sessao do hibernate?

Segue as Livro e o Pom que vc pediu. Lembrando que o projeto é de JSF

@Entity
@Cacheable //A entidade toda sera cacheada com os Selects do LivroDao
@XmlRootElement // Essa anotação indica que o valor da classe será representado como um elemento XML principal.
@XmlAccessorType(XmlAccessType.FIELD) //informa que queremos o acesso através do campo (field):


public class Livro {

    //Pode ser usado os beanValidator conforme as anotações abaixo. Está configurado no jsf_messages.properties

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @NotBlank
    private String titulo;
    @Lob // avisa pro mysql que podera receber mto texto
    @NotBlank
    @Length(min=10, max=1000)
    private String descricao;
    @DecimalMin("20")
    private BigDecimal preco;
    @Min(50)
    private Integer numeroPaginas;
    @ManyToMany
    @Size(min=1)
    @NotNull
    @XmlElement(name="autor")
    @XmlElementWrapper(name="autores")
    private List<Autor> autores = new ArrayList<>();
    @Temporal(TemporalType.DATE)
    private Calendar dataPublicacao;
    private String capaPath;

    //getters e setters
}    
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>br.com.alura</groupId>
    <artifactId>casadocodigo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <build>
        <finalName>casadocodigo</finalName>
    </build>
    <properties>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.spec</groupId>
                <artifactId>jboss-javaee-6.0</artifactId>
                <version>3.0.3.Final</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>javax.annotation</groupId>
                <artifactId>jsr250-api</artifactId>
                <version>1.0</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.jboss.spec.javax.faces</groupId>
            <artifactId>jboss-jsf-api_2.1_spec</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>jsr250-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>8.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.2.Final</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>javax.transaction-api</artifactId>
            <version>1.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.3.6.Final</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.3.6.Final</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.faces</groupId>
            <artifactId>javax.faces-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.omnifaces</groupId>
            <artifactId>omnifaces</artifactId>
            <version>2.7</version>
        </dependency>
    </dependencies>

</project>

Alguma possível solução?

solução!

Descobri que o problema acontecia devido ter o setHint(QueryHints.HINT_CACHEABLE, true) na query. Apos remover, tudo funcionou normalmente.

    public List<Livro> ultimosLancamentos() {
        String jpql = "select l from Livro l join fetch l.autores order by l.dataPublicacao desc";
        return manager.createQuery(jpql, Livro.class).setMaxResults(5).getResultList(); 

    }

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software