I'm trying to make a database based API I have a huge load of data but every time I try to bring the data even with pageable property I get this error:
{
"timestamp": "2022-01-12T01:34:01.851+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.leomanzini.space.flight.news.model.Article.launches, could not initialize proxy - no Session\r\n\tat org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:612)\r\n\tat org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)\r\n\tat org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:591)\r\n\tat org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)\r\n\tat org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:387)\r\n\tat java.base/java.lang.Iterable.forEach(Iterable.java:74)\r\n\tat br.com.leomanzini.space.flight.news.dto.ArticlesDTO.<init>(ArticlesDTO.java:65)\r\n\tat br.com.leomanzini.space.flight.news.service.ArticleService.lambda$findAll$0(ArticleService.java:30)\r\n\tat java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)\r\n\tat java.base/java.util.ArrayList$Itr.forEachRemaining(ArrayList.java:1032)\r\n\tat java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)\r\n\tat java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)\r\n\tat java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)\r\n\tat java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)\r\n\tat java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)\r\n\tat java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)\r\n\tat org.springframework.data.domain.Chunk.getConvertedContent(Chunk.java:173)\r\n\tat org.springframework.data.domain.PageImpl.map(PageImpl.java:106)\r\n\tat br.com.leomanzini.space.flight.news.service.ArticleService.findAll(ArticleService.java:30)\r\n\tat br.com.leomanzini.space.flight.news.controller.SpaceFlightsApiController.findAll(SpaceFlightsApiController.java:28)\r\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:566)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:655)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:764)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.base/java.lang.Thread.run(Thread.java:834)\r\n",
"message": "failed to lazily initialize a collection of role: br.com.leomanzini.space.flight.news.model.Article.launches, could not initialize proxy - no Session",
"path": "/articles"
}
At the database I have an amount of 11795 articles and their respectives relationship with others tables, there is a way to optimize this load or just make it works?
Article entity:
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "article")
public class Article {
@Id
@EqualsAndHashCode.Include
private Long id;
@Column(nullable = false)
private Boolean featured;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String url;
@Column(name = "image_url", nullable = false)
private String imageUrl;
@Column(name = "news_site", nullable = false)
private String newsSite;
@Column(nullable = false)
private String summary;
@Column(name = "published_at", nullable = false)
private String publishedAt;
@ManyToMany(fetch = FetchType.LAZY)
private List<Launches> launches;
@ManyToMany(fetch = FetchType.LAZY)
private List<Events> events;
@Column(name = "inserted_by_human")
private Boolean insertedByHuman = false;
}
Events and Launches entities:
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Events {
@Id
@EqualsAndHashCode.Include
private Long id;
private String provider;
}
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Launches {
@Id
@EqualsAndHashCode.Include
private String id;
private String provider;
}
The repository is just a interface with JpaRepository and the Article as entity.
The service class:
import br.com.leomanzini.space.flight.news.dto.ArticlesDTO;
import br.com.leomanzini.space.flight.news.model.Article;
import br.com.leomanzini.space.flight.news.repository.ArticleRepository;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@Service
@AllArgsConstructor
public class ArticleService {
@Autowired
private final ArticleRepository articleRepository;
public Page<ArticlesDTO> findAll(Pageable pageable) {
Page<Article> articleList = articleRepository.findAll(pageable);
return articleList.map(article -> new ArticlesDTO(article));
}
}
If I just use my entity as a return, the methods work, but when I convert the same to dto the application breaks. The dto class is below:
import br.com.leomanzini.space.flight.news.model.Article;
import lombok.*;
import javax.management.ConstructorParameters;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ArticlesDTO implements Serializable {
@NotEmpty
@EqualsAndHashCode.Include
private Long id;
@NotEmpty
private String title;
@NotEmpty
private String url;
@NotEmpty
private String imageUrl;
@NotEmpty
private String newsSite;
@NotEmpty
private String summary;
@NotEmpty
private String publishedAt;
@NotEmpty
private String updatedAt;
@NotEmpty
private Boolean featured;
@Valid
private List<LaunchesDTO> launches;
@Valid
private List<EventsDTO> events;
public ArticlesDTO (Article article) {
id = article.getId();
title = article.getTitle();
url = article.getUrl();
imageUrl = article.getImageUrl();
newsSite = article.getNewsSite();
summary = article.getSummary();
publishedAt = article.getPublishedAt();
updatedAt = article.getPublishedAt();
featured = article.getFeatured();
launches = new ArrayList<>();
article.getLaunches().forEach(launch -> {
LaunchesDTO launchesDTO = new LaunchesDTO(launch.getId(), launch.getProvider());
launches.add(launchesDTO);
});
events = new ArrayList<>();
article.getEvents().forEach(event -> {
EventsDTO eventsDTO = new EventsDTO(event.getId(), event.getProvider());
events.add(eventsDTO);
});
}
}
There is anyway to fix the error and make it works? Something to accelerate the database load or something else?
The proposed answer was that in the service class, the @Transactional(readOnly = true)
attribute has been enabled, it works fine to resolve the error
failed to lazyly initialize a collection of role: br.com . leomanzini.space.flight.news.model.Article.launches, could not initialize proxy.
The method at service class looked like this:
import br.com.leomanzini.space.flight.news.dto.ArticlesDTO;
import br.com.leomanzini.space.flight.news.model.Article;
import br.com.leomanzini.space.flight.news.repository.ArticleRepository;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@AllArgsConstructor
public class ArticleService {
@Autowired
private final ArticleRepository articleRepository;
@Transactional(readOnly = true)
public Page<ArticlesDTO> findAll(Pageable pageable) {
Page<Article> articleList = articleRepository.findAll(pageable);
return articleList.map(article -> new ArticlesDTO(article));
}
}
And the requisition working fine!