I can not ignore fields when trying to return them as Json causing "Infinite recursion"

4
I'm working with Hibernate , Spring and Jackson (to ignore the fields) and trying to return the User < strong> in a request json java returns error due to @OneToMany and @ManyToOne mapping with the Profile class. Does anyone know why?

Ah, it's important to let me know that I'm working with a number of modules managed by maven :

|--marcenaria-dao

|--marcenaria-service

|--marcenaria-ws

|--marcenaria-web

With this, cabinet-dao contains the beans (User and Profile) and it is dependency of the project joinery-service which in turn is dependency of the joinery-webservice.

Below the exception and classes.

User.java (cabinet-dao)

package br.com.marcenaria.bean;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import com.fasterxml.jackson.annotation.JsonManagedReference;

@Entity
public class Usuario extends BaseBean{

    private static final long serialVersionUID = 9146984943787732965L;

    private String nome;
    private String email;
    private String senha;
    private Perfil perfil;
    private Marcenaria marcenaria;
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Column(nullable=false,unique=true)
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Column(nullable=false,unique=true)
    public String getSenha() {
        return senha;
    }
    public void setSenha(String senha) {
        this.senha = senha;
    }
    @JsonManagedReference(value="perfil")
    @ManyToOne
    @JoinColumn(name = "perfil_id")
    public Perfil getPerfil() {
        return perfil;
    }
    public void setPerfil(Perfil perfil) {
        this.perfil = perfil;
    }
    @Column
    public Date getCriado() {
        return criado;
    }
    public void setCriado(Date criado) {
        this.criado = criado;
    }
    @Column
    public Date getInativo() {
        return inativo;
    }
    public void setInativo(Date inativo) {
        this.inativo = inativo;
    }
    @ManyToOne
    @JoinColumn(name="marcenaria_id")
    public Marcenaria getMarcenaria() {
        return marcenaria;
    }
    public void setMarcenaria(Marcenaria marcenaria) {
        this.marcenaria = marcenaria;
    }
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
}

Profile.java (cabinet-dao)

package br.com.marcenaria.bean;

import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
public class Perfil extends BaseBean{

    private static final long serialVersionUID = -6933398409318466304L;

    private String descricao;
    private List<Usuario> listaUsuario;

    public Perfil() {}

    public Perfil(String descricao) {
        this.descricao = descricao;
    }

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @Column(nullable=false)
    public String getDescricao() {
        return descricao;
    }
    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }
    @JsonIgnore
    @JsonBackReference(value="lista-usuario")
    @OneToMany(mappedBy="perfil")
    public List<Usuario> getListaUsuario() {
        return listaUsuario;
    }
    public void setListaUsuario(List<Usuario> listaUsuario) {
        this.listaUsuario = listaUsuario;
    }
    @Column
    public Date getCriado() {
        return criado;
    }
    public void setCriado(Date criado) {
        this.criado = criado;
    }
    @Column
    public Date getInativo() {
        return inativo;
    }
    public void setInativo(Date inativo) {
        this.inativo = inativo;
    }
}

pom.xml (cabinet-dao)

<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>marcenaria</groupId>
        <artifactId>marcenaria</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>marcenaria-dao</groupId>
    <artifactId>marcenaria-dao</artifactId>
    <name>marcenaria-dao</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.10.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>
    </dependencies>
</project>

UserController.java (cabinet-ws)

package br.com.marcenaria.controller;

import java.util.Arrays;
import java.util.Date;

import javax.servlet.ServletException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import br.com.marcenaria.bean.Usuario;
import br.com.marcenaria.service.UsuarioService;
import br.com.marcenaria.view.Retorno;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@RestController
@RequestMapping("/usuario")
public class UsuarioController {

    @Autowired
    private UsuarioService usuarioService;

    @RequestMapping(value = "login", method = RequestMethod.POST)
    public Retorno<Usuario> login(@RequestBody final Usuario pUsuario)
        throws ServletException {
        Usuario usuario = usuarioService.acessar(pUsuario);

        String token = Jwts.builder().setSubject(usuario.getEmail())
                .claim("roles",Arrays.asList(usuario.getPerfil().getDescricao())).setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, "secretkey").compact();

        Retorno<Usuario> retorno = new Retorno<Usuario>();
        retorno.setObjeto(usuario);
        retorno.setToken(token);

        return retorno;
    }
}

Exception

mar 11, 2016 2:30:15 AM org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver handleHttpMessageNotWritable
ADVERTÊNCIA: Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion (StackOverflowError) (through reference chain: br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]->br.com.marcenaria.bean.Usuario["perfil"]->br.com.marcenaria.bean.Perfil["listaUsuario"]->org.hibernate.collection.internal.PersistentBag[0]-
    
asked by anonymous 11.03.2016 / 06:57

1 answer

4

You have here a case of infinite recursion due to the bi-directional relationship.

Let's say John is an Admin :

  • The object of type Usuário John therefore has a reference to Perfil Admin .
  • The Perfil object in question, in turn, has a list of users, which includes John .

On the Java side this is no problem, references are just notes for pieces of memory. At the time of writing% John in JSON this will result in an infinite tree.

I noticed that you are trying to use the Usuário annotation to try to solve the problem. See if you're using the correct package . Other options are "dismount" (in the absence of a good technical translation for the term detach ) the object of type @JsonIgnore and set the value of Perfil to listaUsuario , or create a new class for the view layer (Eg, A% with% where profile is a null )

    
11.03.2016 / 13:40