1

I'm working with Java 1.8 in a relationship between entities @OneToMany and @ManyToOne with Spring-MVC and Spring-Data-JPA, but I am getting the following errors:

GRAVE: Servlet.service() for servlet [appServlet] in context with path [/adi] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.coderi.adi.model.Usuario.papeis, could not initialize proxy - no Session] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.coderi.adi.model.Usuario.papeis, could not initialize proxy - no Session

I can add a user (Usuario) and their roles (Papeis), but to perform the query always get the above error.

Entity Usuario:

@Entity
public class Usuario {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @NotEmpty
    private String nome;

    @NotEmpty
    private String email;

    @NotEmpty
    @Size(min = 2, max = 25)
    @Column(unique = true)
    private String login;

    @NotEmpty
    @Size(min = 6)
    private String senha;

    @Transient
    private String confirmSenha;

    private Boolean status;

    @OneToMany(mappedBy = "usuario")
    private List<Papel> papeis;

    <!-- Getters/Setters... -->
}

Entity Papel:

@Entity
public class Papel {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @NotEmpty
    private String papel;

    @ManyToOne
    private Usuario usuario;

    <!-- Getters/Setters... -->
}

A user (Usuario) can have multiple roles (Papel), the various roles must belong to a user. This is the correct approach?

The Service:

@Service
public class PapelService {

    @Autowired
    private PapelReposiroty papelRepository;

    public Papel getPapel(Integer id) {
        return papelRepository.findOne(id);
    }

    public Papel adicionar(Papel papel) {
        return papelRepository.save(papel);
    }

    public List<Papel> listarPapeisPorUsuario(Usuario usuario) {
        return papelRepository.findPapelByUsuario(usuario);
    }
}

The Repository:

@Repository
public interface PapelReposiroty extends CrudRepository<Papel, Integer> {
    public List<Papel> findPapelByUsuario(Usuario usuario);
}

In my Controller after adding a user/roles when I execute papelService.getPapel(1) I get this cited error. Thanks for your help!

Ps: The error occurs only when using the methods of relationships.

Database: Database

All stack trace:

GRAVE: Servlet.service() for servlet [appServlet] in context with path [/adi] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.coderi.adi.model.Usuario.papeis, could not initialize proxy - no Session] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.coderi.adi.model.Usuario.papeis, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:579)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:203)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:558)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:131)
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:509)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at br.com.coderi.adi.model.Usuario.toString(Usuario.java:113)
at java.lang.String.valueOf(String.java:2982)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at br.com.coderi.adi.model.Papel.toString(Papel.java:66)
at java.lang.String.valueOf(String.java:2982)
at java.io.PrintStream.println(PrintStream.java:821)
at org.apache.tomcat.util.log.SystemLogHandler.println(SystemLogHandler.java:267)
at br.com.coderi.adi.controller.PapelController.adicionarForm(PapelController.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:112)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:206)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:106)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
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:142)
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:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Thiago Pereira
  • 594
  • 13
  • 25
  • 1
    I guess the problem was not due to this line `papelService.getPapel(1) `. some where when you call `Usuario.getPapeis()` it raised the error. So you need to modify your mapping to `@OneToMany(fetch = FetchType.EAGER, mappedBy = "usuario")` – Mai Hữu Lợi Jul 08 '16 at 02:11
  • @MaiHữuLợi can you be more specific? So I can add more information. – Thiago Pereira Jul 08 '16 at 02:14
  • Please see my edit. – Mai Hữu Lợi Jul 08 '16 at 02:18
  • @MaiHữuLợi thanks for your attention. I add the full trace. – Thiago Pereira Jul 08 '16 at 02:25
  • You can see that the log util of java was calling to the line `br.com.coderi.adi.model.Usuario.toString(Usuario.java:113)` you can see it. From here it call to `Usuario.getPapeis()`. and it raise the error due to lazy load. 2 solution for you: 1) using EAGER load as the comment above or 2) remove the log util (I suggest to use log4j). – Mai Hữu Lợi Jul 08 '16 at 02:33
  • @MaiHữuLợi I think my mistake is in the `toString()` `@Override public String toString() { return "Usuario [id=" + id + ", nome=" + nome + ", email=" + email + ", login=" + login + ", senha=" + senha + ", confirmSenha=" + confirmSenha + ", status=" + status + ", papeis=" + papeis + "]"; }` – Thiago Pereira Jul 08 '16 at 02:46
  • 1
    OK `+ papeis + "]"` Here is where it come from. – Mai Hữu Lợi Jul 08 '16 at 02:58
  • http://pt.stackoverflow.com – Victor Stafusa - BozoNaCadeia Jul 08 '16 at 03:36
  • Possible duplicate of [Solve "failed to lazily initialize a collection of role" exception](http://stackoverflow.com/questions/11746499/solve-failed-to-lazily-initialize-a-collection-of-role-exception) – Nikem Jul 08 '16 at 05:00

2 Answers2

2

How to Enable Lazy Loading in Hibernate

Before moving further, it is important to recap the default behavior of lazy loading in case of using hibernate mappings vs annotations.

The default behavior is to load ‘property values eagerly’ and to load ‘collections lazily’. Contrary to what you might remember if you have used plain Hibernate 2 (mapping files) before, where all references (including collections) are loaded eagerly by default. Also note that @OneToMany and @ManyToMany associations are defaulted to LAZY loading; and @OneToOne and @ManyToOne are defaulted to EAGER loading. This is important to remember to avoid any pitfall in future.

To enable lazy loading explicitly you must use "fetch = FetchType.LAZY" on a association which you want to lazy load when you are using hibernate annotations.

An example usage will look like this:

@OneToMany( mappedBy = "category", fetch = FetchType.LAZY ) private Set products; Another attribute parallel to "FetchType.LAZY" is "FetchType.EAGER" which is just opposite to LAZY i.e. it will load association entity as well when owner entity is fetched first time.

How Lazy Loading Works in Hibernate

The simplest way that Hibernate can apply lazy load behavior upon your entities and associations is by providing a proxy implementation of them. Hibernate intercepts calls to the entity by substituting a proxy for it derived from the entity’s class. Where the requested information is missing, it will be loaded from the database before control is ceded to the parent entity’s implementation.

Please note that when the association is represented as a collection class, then a wrapper (essentially a proxy for the collection, rather than for the entities that it contains) is created and substituted for the original collection. When you access this collection proxy then what you get inside returned proxy collection are not proxy entities; rather they are actual entities. You need not to put much pressure on understanding this concept because on runtime it hardly matters.

You use @OnetoMany relation.

I know to solve.

You use fetch.

Your entity

@Entity
public class Usuario {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @NotEmpty
    private String nome;

    @NotEmpty
    private String email;

    @NotEmpty
    @Size(min = 2, max = 25)
    @Column(unique = true)
    private String login;

    @NotEmpty
    @Size(min = 6)
    private String senha;

    @Transient
    private String confirmSenha;

    private Boolean status;

    @OneToMany(mappedBy = "usuario")
    private List<Papel> papeis;

    <!-- Getters/Setters... -->
}

You search "jpa fetch lazy". but. fetch, many search relation. :)

0gam
  • 1,343
  • 1
  • 9
  • 21
  • thanks for your attention. Works with `@OneToMany(mappedBy = "usuario", fetch = FetchType.EAGER)`, but not with `FetchType.LAZY`. You know why? – Thiago Pereira Jul 08 '16 at 03:22
  • Your choice well. just i want to search lazy. your error : failed to lazily initialize a collection of role. why happen error? – 0gam Jul 08 '16 at 03:59
2

The reason why IT is not working is because your session is getting closed. This can happen automaticaly after transaction END. Then the entity enters "detached" state. When this happens all access to uninitialized lazy proxies will result in this exception.Of course the easiest fix is to mark IT AS EAGER. If you want to keep IT lazy though In order to fix IT you need to initialize this collection within a transaction before IT become detached. The alternative if you dont wrap your service in transactin is to use HQL query with fetch clause to ensure the collection is initialized. If you follow these steps you can keep the LAZY FetchType

Alexander Petrov
  • 9,204
  • 31
  • 70