title: Spring JSON Direct self-reference leading to cycle (infinite recursion)
body: <p>I'm writing a simple Spring MVC REST web service using Spring Framework and Hibernate.</p>
  
  <p>I want to serialize the following simple user entity:</p>
  
  <p>Pseudo-code:</p>
  
  <pre><code>@Entity
  public class UserEntity implements Serializable
  {
     @Id
     @GeneratedValue(
         strategy = GenerationType.IDENTITY)
     @JsonView(Views.BaseView.class)
     @JsonProperty(value = "id")
     @Column(name = "id_user")
     private Integer id;
  
     @JsonView(Views.UserView.class)
     @JsonProperty(value = "login")
     @Column(name = "login")
     private String login;
  
     @JsonView(Views.UserView.class)
     @JsonProperty(value = "password")
     @Column(name = "password")
     private String password;
  
     @JsonView(Views.UserView.class)
     @JsonProperty(value = "creator")
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "id_creator", 
          referencedColumnName = "id_user")
     private UserEntity creator;
  
     //Accessors
  }
  </code></pre>
  
  <p>Views description file:</p>
  
  <pre><code>public class Views
  {
      public interface BaseView                          {}
      public interface UserView extends BaseView         {}
  }
  </code></pre>
  
  <p>I want the following JSON output:</p>
  
  <pre><code>{
    "id": 2,
    "login": "toto",
    "password": "password2",
    "creator": {
        "id": 1,
        "login": "tata",
        "password": "password1"   
  
     }
  }
  </code></pre>
  
  <p>Unfortunatly, I have the following exception:</p>
  
  <pre><code>org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Direct self-reference leading to cycle (through reference chain: com.az.metal.entity.UserEntity["creator"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Direct self-reference leading to cycle (through reference chain: com.az.metal.entity.UserEntity["creator"])
      org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:292)
      org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
      org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:231)
      org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:203)
      org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
      org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:132)
      org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
      org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
      org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
      org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
      org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
      org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
      org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
      org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
      org.sitemesh.webapp.contentfilter.ContentBufferingFilter.bufferAndPostProcess(ContentBufferingFilter.java:169)
      org.sitemesh.webapp.contentfilter.ContentBufferingFilter.doFilter(ContentBufferingFilter.java:126)
      org.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:120)
      org.sitemesh.config.ConfigurableSiteMeshFilter.doFilter(ConfigurableSiteMeshFilter.java:163)
      org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
      org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
      org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
      org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
      org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
      org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
  cause mère
  
  com.fasterxml.jackson.databind.JsonMappingException: Direct self-reference leading to cycle (through reference chain: com.az.metal.entity.UserEntity["creator"])
      com.fasterxml.jackson.databind.ser.BeanPropertyWriter._handleSelfReference(BeanPropertyWriter.java:899)
      com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:687)
      com.fasterxml.jackson.databind.ser.impl.FilteredBeanPropertyWriter$SingleView.serializeAsField(FilteredBeanPropertyWriter.java:67)
      com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)
      com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
      com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130)
      com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1387)
      com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:889)
      org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:285)
      org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
      org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:231)
      org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:203)
      org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
      org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:132)
      org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
      org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
      org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
      org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
      org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
      org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
      org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
      org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
      org.sitemesh.webapp.contentfilter.ContentBufferingFilter.bufferAndPostProcess(ContentBufferingFilter.java:169)
      org.sitemesh.webapp.contentfilter.ContentBufferingFilter.doFilter(ContentBufferingFilter.java:126)
      org.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:120)
      org.sitemesh.config.ConfigurableSiteMeshFilter.doFilter(ConfigurableSiteMeshFilter.java:163)
      org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
      org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
      org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
      org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
      org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
      org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
      org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
  </code></pre>
  
  <p>I understand the problem comes from an infinite recursion during JSON serialization process.</p>
  
  <p>I could not find the solution to serialize my User entity with its creator together.</p>
  
  <p>Thanks a lot in advance for your help!</p>